Java Socket实现的一个简易聊天室

时间:2022-05-30 10:08:09

大体思路:用一个ServerSocket来接收所有Client的消息,然后转发给其他Client。在Server端,每个Client对应一个ServerHandleThread线程。在Client端,开一个线程来接收Server端的消息,main线程来接收键盘的输入。具体细节见代码。

Server端代码

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

public static void main(String args[]) {
try {
ServerSocket serverSocket = new ServerSocket(4710);
while (true) {
Socket socket = serverSocket.accept();
new ServerHandleThread(socket);
}
} catch (IOException e) {
e.printStackTrace();
}
}

}

ServerHandleThread代码

import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class ServerHandleThread extends Thread {

static List<ServerHandleThread> mServerHandleThreadList = new ArrayList<>();

private Socket mSocket;
private BufferedReader mBufferedReader;
private PrintWriter mPrintWriter;
private String mClientNickname;

public ServerHandleThread(Socket socket) {
mSocket = socket;
start();
}

@Override
public void run() {
try {
mBufferedReader = new BufferedReader(
new InputStreamReader(mSocket.getInputStream()));
mPrintWriter = new PrintWriter(
new OutputStreamWriter(mSocket.getOutputStream()));
mPrintWriter.println("请输入昵称!");
mPrintWriter.flush();
mClientNickname = mBufferedReader.readLine();
mServerHandleThreadList.add(this);
sendMsgToAll(mClientNickname + "加入聊天室");
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
String s = mBufferedReader.readLine();
if (s.equals("bye!")) {
sendMsgToAll(mClientNickname + "退出了聊天室");
mPrintWriter.println(s);
mPrintWriter.flush();
mBufferedReader.close();
mPrintWriter.close();
mSocket.close();
break;
}
for (int i = 0;i < mServerHandleThreadList.size();i++) {
if (!mServerHandleThreadList.get(i).getClientNickname().equals(
mClientNickname)) {
mServerHandleThreadList.get(i).getPrintWriter().println(
mClientNickname + ":" + s);
mServerHandleThreadList.get(i).getPrintWriter().flush();
} else {
mServerHandleThreadList.get(i).getPrintWriter().println("Me:" + s);
mServerHandleThreadList.get(i).getPrintWriter().flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

void sendMsgToAll(String msg) {
for (int i = 0;i < mServerHandleThreadList.size();i++) {
mServerHandleThreadList.get(i).getPrintWriter().println(msg);
mServerHandleThreadList.get(i).getPrintWriter().flush();
}
}

public PrintWriter getPrintWriter() {
return mPrintWriter;
}

public String getClientNickname() {
return mClientNickname;
}
}
ClientOne代码

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class ClientOne {

private static boolean flag = true;

public static void main(String[] args) {
BufferedReader mBufferedReader;
PrintWriter mPrintWriter;
try {
Socket socket = new Socket("localhost", 4710);
mBufferedReader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
mPrintWriter = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream()));
new Thread(new Runnable() {
@Override
public void run() {
while (flag) {
try {
String s = mBufferedReader.readLine();
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
while (!s.equals("bye!")) {
mPrintWriter.println(s);
mPrintWriter.flush();
s = scanner.nextLine();
}
mPrintWriter.println(s);
mPrintWriter.flush();
mBufferedReader.close();
mPrintWriter.close();
socket.close();
scanner.close();
flag = false;
} catch (IOException e) {
e.printStackTrace();
}
}

}
至于ClientTwo,ClientThree之类的,改个类名就可以了。