Java网络编程实现一(服务器)对多(客户端)

使用多线程+网络编程实现一个服务器对多个客户端

在该程序中用到的知识点

  1. java的BIO
  2. ServerSocket和Socket 网络编程
  3. 多线程的知识(个人认为重要)

实现的思路

服务器端(使用多个线程)

  1. 在客户端需要有一个集合来存储已经连接上的客户端, 如果客户端断开连接则需要从集合中删除
  2. 创建一个线程来处理客户端的连接
  3. 每一个客户端的连接都需要一个线程来接收客户端的请求
  4. 使用主线程来给客户端发送数据(轮询客户端集合中的Socket给客户端发送数据)

客户端(使用两个线程)

  1. 首先创建一个线程来接收服务器端的数据
  2. 使用主线程来给服务器端发送数据

效果的演示

  1. 启动服务器端

在这里插入图片描述

  1. 启动客户端
    在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

4、 在服务器端发送数据,在已经连接上的客户端中可以接受到消息
在这里插入图片描述
在这里插入图片描述

  1. 客户端退出,服务器端有提示
    在这里插入图片描述

  2. 服务器端退出,所有的客户端有提示,并且客户端全部断开连接
    在这里插入图片描述

代码演示

服务器端

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();}}}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部