描述
实现多个客户端即时通讯的程序,服务器只起到了转发消息的作用。
核心代码
- 服务端 CommunicationClient.java
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CommunicationClient {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ExecutorService es = Executors.newSingleThreadExecutor();
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 = scanner.nextLine();
Message message = new Message(name, null, MessageType.TYPE_LOGIN, null);
oos.writeObject(message);
// message = (Message) ois.readObject();
// System.out.println(message.getInfo() + message.getFrom());
// 启动读取消息的现成
es.execute(new ReadInfoThread(ois));
// 通过主线程来发送消息
boolean flag = true;
while (flag) {
message = new Message();
System.out.println("TO:");
message.setTo(scanner.nextLine());
message.setFrom(name);
message.setType(MessageType.TYPE_SEND);
System.out.println("Info:");
message.setInfo(scanner.nextLine());
oos.writeObject(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ReadInfoThread implements Runnable {
private ObjectInputStream in;
private boolean flag = true;
public void setFlag(boolean flag) {
this.flag = flag;
}
public ReadInfoThread(ObjectInputStream in) {
this.in = in;
}
@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 (Exception e) {
e.printStackTrace();
}
}
}
- 客户端 CommunicationClient.java
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CommunicationClient {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ExecutorService es = Executors.newSingleThreadExecutor();
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 = scanner.nextLine();
Message message = new Message(name, null, MessageType.TYPE_LOGIN, null);
oos.writeObject(message);
// message = (Message) ois.readObject();
// System.out.println(message.getInfo() + message.getFrom());
// 启动读取消息的现成
es.execute(new ReadInfoThread(ois));
// 通过主线程来发送消息
boolean flag = true;
while (flag) {
message = new Message();
System.out.println("TO:");
message.setTo(scanner.nextLine());
message.setFrom(name);
message.setType(MessageType.TYPE_SEND);
System.out.println("Info:");
message.setInfo(scanner.nextLine());
oos.writeObject(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ReadInfoThread implements Runnable {
private ObjectInputStream in;
private boolean flag = true;
public void setFlag(boolean flag) {
this.flag = flag;
}
public ReadInfoThread(ObjectInputStream in) {
this.in = in;
}
@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 (Exception e) {
e.printStackTrace();
}
}
}
- 通用类 Message.java
import java.io.Serializable;
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;
}
}
- 通用类 MessageType .java
public final class MessageType {
// 登陆消息类型
public static final int TYPE_LOGIN = 0x1;
// 发送消息的类型
public static final int TYPE_SEND = 0x2;
}