Java网络编程实现一(服务器)对多(客户端)
使用多线程+网络编程实现一个服务器对多个客户端
在该程序中用到的知识点
- java的BIO
- ServerSocket和Socket 网络编程
- 多线程的知识(个人认为重要)
实现的思路
服务器端(使用多个线程)
- 在客户端需要有一个集合来存储已经连接上的客户端, 如果客户端断开连接则需要从集合中删除
- 创建一个线程来处理客户端的连接
- 每一个客户端的连接都需要一个线程来接收客户端的请求
- 使用主线程来给客户端发送数据(轮询客户端集合中的Socket给客户端发送数据)
客户端(使用两个线程)
- 首先创建一个线程来接收服务器端的数据
- 使用主线程来给服务器端发送数据
效果的演示
- 启动服务器端

-
启动客户端

启动客户端后,服务器端可以监听到连接

- 在客户端中发送数据在服务端可以接收到


4、 在服务器端发送数据,在已经连接上的客户端中可以接受到消息


-
客户端退出,服务器端有提示

-
服务器端退出,所有的客户端有提示,并且客户端全部断开连接

代码演示
服务器端
public class Server {public static void main(String[] args) {List<Socket> socketList = new ArrayList<>();// 开启线程接收客户端的连接new Thread(new AcceptSocket(socketList)).start();while (true) {Scanner scanner = new Scanner(System.in);String sendInfo = scanner.nextLine();// 循环向所有的客户端发送消息socketList.forEach(socket -> {try {PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));printWriter.println(sendInfo);printWriter.flush();} catch (SocketException e) {System.out.println(1);} catch (IOException e) {e.printStackTrace();}});}}
}// 接收客户端Socket线程
class AcceptSocket implements Runnable {List<Socket> socketList;public AcceptSocket(List<Socket> socketList) {this.socketList = socketList;}@Overridepublic void run() {ServerSocket serverSocket = null;try {serverSocket = new ServerSocket(9000);System.out.println("监听客户端的连接");// 循环接收客户端的请求while (true) {Socket socket = serverSocket.accept();// 接收到后加入到 socketListsocketList.add(socket);// 开启处理客户端线程new Thread(new HandleSocket(socket, socketList)).start();}} catch (SocketException e) {System.out.println(2);} catch (IOException e) {e.printStackTrace();} finally {// 关闭连接try {if (null != serverSocket) {serverSocket.close();}} catch (IOException e) {e.printStackTrace();}}}
}// 处理客户端Socket线程
class HandleSocket implements Runnable {Socket socket;List<Socket> socketList;public HandleSocket(Socket socket, List<Socket> socketList) {this.socket = socket;this.socketList = socketList;}@Overridepublic void run() {BufferedReader bufferedReader = null;try {// 读取客户端发来的数据bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));System.out.println("等待读取客户端:" + socket.getLocalAddress().toString().substring(1) + ":" + socket.getPort() + " 的消息");while (true) {String clientInfo = bufferedReader.readLine();System.out.println(socket.getLocalAddress().toString().substring(1) + ":" + socket.getPort() + "发送的消息是:" + clientInfo);}} catch (SocketException e) {// 强制关闭连接后的处理System.out.println(socket.getLocalAddress().toString().substring(1) + ":" + socket.getPort() + "断开连接");// 将该连接从socketList中移除socketList.remove(socket);} catch (IOException e) {e.printStackTrace();} finally {// 关闭连接try {if (null != bufferedReader) {bufferedReader.close();}if (null != socket) {bufferedReader.close();}} catch (IOException e) {e.printStackTrace();}}}
}
客户端
public class Client {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);Socket socket = null;PrintWriter printWriter = null;try {socket = new Socket("localhost", 9000);printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));//开启线程接收服务端的消息new Thread(new AcceptServer(socket)).start();System.out.println("可以给服务器端发送数据了");while (true) {// 给服务端发送消息String sendInfo = scanner.nextLine();printWriter.println(sendInfo);printWriter.flush();}} catch (IOException e) {e.printStackTrace();} finally {// 关闭连接try {if (null != socket) {socket.close();}if (null != printWriter) {printWriter.close();}} catch (IOException e) {e.printStackTrace();}}}
}class AcceptServer implements Runnable {Socket socket;public AcceptServer(Socket socket) {this.socket = socket;}@Overridepublic void run() {BufferedReader bufferedReader = null;try {bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));while (true) {String serverInfo = bufferedReader.readLine();System.out.println("服务器的消息为:" + serverInfo);}} catch (SocketException e) {System.out.println("服务器异常关闭");// 退出System.exit(0);} catch (IOException e) {e.printStackTrace();} finally {// 关闭连接try {if (null != bufferedReader) {bufferedReader.close();}if (null != socket) {socket.close();}} catch (IOException e) {e.printStackTrace();}}}
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
