public class ServerTest { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(12345); /** * 死循环接收客户端请求,accept会阻塞 */ while (true){ //阻塞等待客户端连接 Socket clientSocket = serverSocket.accept(); try(PrintStream outputStream = new PrintStream(clientSocket.getOutputStream())) { outputStream.println("Hello,请求已收到。"); }finally { clientSocket.close(); } } } }
客户端Socket:
public class ClientTest { public static void main(String[] args) throws IOException { try (Socket clientSocket = new Socket("127.0.0.1",12345); BufferedReader clientIn = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));){ String line = clientIn.readLine(); System.out.println("收到服务端返回:" + line); } } }
package tcpandudp.threadssockettest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * @ClassName Server * @projectName: object1 * @author: Zhangmingda * @description: 群发消息 * date: 2021/5/11. */ public class Server { private static Set<Socket> sockets = Collections.synchronizedSet(new HashSet<>()); private static class MyRunnable implements Runnable { /** * 当前线程要处理的客户端Socket */ private Socket socket; /** * @param socket 构造客户端socket */ public MyRunnable(Socket socket) { this.socket = socket; } /** * 具体处理每个客户端连接请求的逻辑,封装到线程run方法中 */ @Override public void run() { //获取客户端发送来的数据 String content = null; try (BufferedReader br = new BufferedReader(new InputStreamReader(this.socket.getInputStream()))){ /** * 每次读取一行,读取一行就广播给所有客户端,直到读尽,阻塞住, */ while ((content = br.readLine()) != null){ //广播给所有客端 通过socket.getOutputStream()获取输出流OutputStream for (Socket s : sockets){ PrintStream printStream = new PrintStream(s.getOutputStream()); printStream.println(content); } } }catch (SocketException e){ System.out.println(socket.getInetAddress() + "已断开");; } catch (IOException e) { e.printStackTrace(); }finally { /** * 当客户端断开连接while循环跳出,关闭客户端连接,从客户端Set集合中移除客户端Socket */ sockets.remove(this.socket); try { this.socket.close(); } catch (IOException e) { e.printStackTrace(); }finally { this.socket = null; } } } } public static void main(String[] args) throws IOException { /** * 服务端监听端口 */ ServerSocket serverSocket = new ServerSocket(8888); /** * 启动后一直等待客户端连接,获取到一个客户端就保存到客户端集合中, * 然后启动一个新的线程处理对应客户端请求, * 主线程再次等待新的客户端建联 */ while (true){ Socket client = serverSocket.accept(); sockets.add(client); new Thread(new MyRunnable(client)).start(); } } }
package tcpandudp.threadssockettest; import java.io.*; import java.net.Socket; /** * @ClassName ClientTest * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/5/11. */ public class ClientTest { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1",8888); /** * 启动一个线程持续读取服务端返回的数据 */ new Thread(){ @Override public void run() { String content = null; try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()))){ //阻塞式等待服务端回复的数据 while ((content = bufferedReader.readLine()) != null){ System.out.println("收到服务端返回数据:" + content); } } catch (IOException e) { e.printStackTrace(); } } }.start(); /** * 主线程发送数据 */ try (PrintStream printStream = new PrintStream(socket.getOutputStream()); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)) ){ String line = null; /** * 如果输入的不是exit字符串,就发送输入的数据,然后一直死循环阻塞等待再次输入数据 * 获取到了字符,内容是exit while循环false 退出 */ while ((line = bufferedReader.readLine()) != null && !line.equals("exit")){ printStream.println(line); } } } }
使用线程安全的ConcurrentHashMap记录客户端Socket信息(要求客户端连接后提供用户名):
原文:https://www.cnblogs.com/zhangmingda/p/14769044.html