赞
踩
Socket的本质是编程接口,是对TCP/IP协议的具体实现,各种编程语言均有自己的实现,可以直接给程序员调用使用。本质是建立端口与端口间的网络通信。
在java的实际开发中,很少会自己直接使用Socket编程,一般借助第三方写好的工具类或框架。在阅读第三方框架工具的源码中,可能会存在Socket的操作。
public class DemoServer { public static void main(String[] args) throws IOException { //创建服务端socket,监听tcp 8080端口。 ServerSocket serverSocket = new ServerSocket(8080); while (true){ //阻塞等待tcp客户端连接,连接好后会创建返回一个Socket对象。 Socket clientSocket = serverSocket.accept(); System.out.println(clientSocket.getInetAddress()+" "+clientSocket.getPort()); handleSocket(clientSocket); } } //新建线程处理连接的Socket客户端发送的消息 private static void handleSocket(Socket socket){ new Thread(()->{ byte[] bufferBytes = new byte[1024]; InputStream in = null; OutputStream out = null; try { in = socket.getInputStream(); out = socket.getOutputStream(); while (true){ //阻塞读取tcp客户端发送的消息 int readCount = in.read(bufferBytes); if(readCount!=-1){ String str = new String(bufferBytes, 0, readCount); System.out.println("服务端接收到的信息:"+str); //回送消息给客户端 out.write(bufferBytes,0,readCount); out.flush(); }else { System.out.println("socket客户端异常断开"); break; } } }catch (IOException e){ e.printStackTrace(); }finally { closeIO(out); closeIO(in); closeIO(socket); } }).start(); } //关闭流方法 private static void closeIO(Closeable io){ if(io!=null){ try{ io.close(); }catch (IOException e){ e.printStackTrace(); } } } }
public class DemoClient { public static void main(String[] args) throws IOException { //创建Socket Socket socket = new Socket(); //Socket连接指定ip、port socket.connect(new InetSocketAddress("127.0.0.1", 8080)); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); handleMsg(in); Scanner scanner = new Scanner(System.in); boolean flag = true; while (flag){ String str = scanner.next(); if("exit".equals(str)){ flag = false; } out.write(str.getBytes()); out.flush(); } closeIO(out); closeIO(in); closeIO(socket); } //新建线程处理服务端Socket发送的消息 public static void handleMsg(InputStream in){ new Thread(()->{ try { byte[] bufferBytes = new byte[1024]; while (true){ int read = in.read(bufferBytes); if(read!=-1){ String str = new String(bufferBytes, 0, read); System.out.println("客户端接收到消息:"+str); }else { break; } } } catch (IOException e) { e.printStackTrace(); }finally { closeIO(in); } }).start(); } //关闭流方法 private static void closeIO(Closeable io){ if(io!=null){ try{ io.close(); }catch (IOException e){ e.printStackTrace(); } } } }
按照上面的编码方式,每建立一个socket连接,服务端都会新建一个线程处理与之对应的socket数据读写。
若服务端同时接收太多的socket连接,会让服务端消耗过多内存,大量的线程抢占CPU资源也会增大服务器压力。所谓的C10K(connect 10 kilo=>万连接场景)、C10M(connect 10 million=>千万连接场景)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。