多客户端之间的通信(模拟聊天室)
程序员文章站
2024-03-22 15:05:04
...
客户端的数据包通过服务器中转,发送到另一个客户端,
public class Message implements Serializable {
//消息包
private String from;//发送者
private String to;//接收者
private int type;//消息类型
private String info;//消息
public Message() {
}
public Message(String from, String to, int type, String info) {
this.from = from;
this.to = to;
this.type = type;
this.info = info;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "Message{" +
"from='" + from + '\'' +
", to='" + to + '\'' +
", type=" + type +
", info='" + info + '\'' +
'}';
}
}
public final class MessageType {
public static final int TYPE_LOGIN = 0x1;//登陆消息类型
public static final int TYPE_SEND = 0x2;//发送消息类型
}
public class Server {
//服务器端
public static void main(String[] args) {
//用来保存客户端处理的线程
Vector<UserThread> vector = new Vector<>();
ExecutorService es = Executors.newFixedThreadPool(5);
//创建服务器端的Socket
try {
ServerSocket server = new ServerSocket(8888);
System.out.println("服务器已启动,正在等待连接");
while (true){
Socket socket = server.accept();
UserThread user = new UserThread(socket,vector);
es.execute(user);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//客户端处理的线程
class UserThread implements Runnable{
private String name;//客户端的用户名称(唯一)
private Socket s;
private Vector<UserThread> vector;//客户端处理线程的集合
private ObjectInputStream ois;
private ObjectOutputStream oos;
private boolean flag = true;
public UserThread(Socket s,Vector<UserThread> vector){
this.s = s;
this.vector = vector;
vector.add(this);//当前线程添加到集合中
}
@Override
public void run() {
try{
System.out.println("客户端"+s.getInetAddress().getHostAddress()+"已连接");
ois = new ObjectInputStream(s.getInputStream());
oos = new ObjectOutputStream(s.getOutputStream());
while (flag){
//读取消息对象
Message msg = (Message) ois.readObject();
int type = msg.getType();
switch (type){
case MessageType.TYPE_SEND:
String to = msg.getTo();
UserThread ut;
int size = vector.size();
for (int i = 0; i < size; i++) {
ut = vector.get(i);
if (to.equals(ut.name) && ut != this){
ut.oos.writeObject(msg);
break;
}
}
break;
case MessageType.TYPE_LOGIN:
name = msg.getFrom();
msg.setInfo("欢迎你:");
oos.writeObject(msg);
break;
}
}
oos.close();
ois.close();
}catch (IOException | ClassNotFoundException e){
e.printStackTrace();
}
}
}
public class Client {
public static void main(String[] args) {
ExecutorService es = Executors.newSingleThreadExecutor();
Scanner input = new Scanner(System.in);
try {
Socket socket = new Socket("localhost",8888);
System.out.println("服务器连接成功");
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
//向服务器发送登陆信息
System.out.println("请输入名称:");
String name = input.nextLine();
Message msg = new Message(name,null,MessageType.TYPE_LOGIN,null);
oos.writeObject(msg);
msg = (Message) ois.readObject();
System.out.println(msg.getInfo()+msg.getFrom());
//启动读取消息的线程
es.execute(new ReadInfoThread(ois));
//使用主线程来实现发送消息
boolean flag = true;
while (flag){
msg = new Message();
System.out.println("To:");
msg.setTo(input.nextLine());
msg.setFrom(name);
msg.setType(MessageType.TYPE_SEND);
System.out.println("Info:");
msg.setInfo(input.nextLine());
oos.writeObject(msg);
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
//读取消息
class ReadInfoThread implements Runnable{
private ObjectInputStream in;
private boolean flag = true;
public ReadInfoThread(ObjectInputStream in){
this.in = in;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
try{
while (flag){
Message message = (Message) in.readObject();
System.out.println("["+message.getFrom()+"]对我说:"+message.getInfo());
}
if (in != null){
in.close();
}
}catch (IOException | ClassNotFoundException e){
e.printStackTrace();
}
}
}
上一篇: LeetCode 206.翻转链表
推荐阅读
-
多客户端之间的通信(模拟聊天室)
-
java多线程实现服务器端与多客户端之间的通信
-
java多线程实现服务器端与多客户端之间的通信
-
面向UDP的Android——PC双向通信(三):在Android客户端和PC服务器端之间传输自定义对象
-
socket实现客户端与服务端之间的Tcp通信
-
使用send/recv实现TCP客户端服务器之间的双向通信
-
网络编程(InetAddress类、Socket和ServerSocket、实现客户端和服务器之间的双向通信)
-
实现服务器和多个客户端之间的同时通信过程(线程)
-
NIO实现的服务端与客户端之间的简单通信
-
小弟我想学习桌面用C++写的客户端和网页中用PHP写的程序之间通信的原理和知识,请知道的进来指点一上