Java Socket重要参数讲解

发表于:2012-2-16 09:52

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:ggjucheng    来源:51Testing软件测试网采编

  Java Socket的api可能很多人会用,但是Java Socket的参数可能很多人都不知道用来干嘛的,甚至都不知道有这些参数。

  backlog

  用于ServerSocket,配置ServerSocket的最大客户端等待队列。等待队列的意思,先看下面代码

  1. public class Main {  
  2.     public static void main(String[] args) throws Exception {  
  3.         int port = 8999;  
  4.         int backlog = 2;  
  5.         ServerSocket serverSocket = new ServerSocket(port, backlog);  
  6.         Socket clientSock = serverSocket.accept();  
  7.         System.out.println("revcive from " + clientSock.getPort());  
  8.         while (true) {  
  9.             byte buf[] = new byte[1024];  
  10.             int len = clientSock.getInputStream().read(buf);  
  11.             System.out.println(new String(buf, 0, len));  
  12.         }  
  13.     }  
  14. }

  这段测试代码在第一次处理一个客户端时,就不会处理第二个客户端,所以除了第一个客户端,其他客户端就是等待队列了。所以这个服务器最多可以同时连接3个客户端,其中2个等待队列。大家可以telnet localhost 8999测试下。

  这个参数设置为-1表示无限制,默认是50个最大等待队列,如果设置无限制,那么你要小心了,如果你服务器无法处理那么多连接,那么当很多客户端连到你的服务器时,每一个TCP连接都会占用服务器的内存,最后会让服务器崩溃的。

  另外,就算你设置了backlog为10,如果你的代码中是一直Socket clientSock = serverSocket.accept(),假设我们的机器最多可以同时处理100个请求,总共有100个线程在运行,然后你把在100个线程的线程池处理clientSock,不能处理的clientSock就排队,最后clientSock越来越多,也意味着TCP连接越来越多,也意味着我们的服务器的内存使用越来越高(客户端连接进程,肯定会发送数据过来,数据会保存到服务器端的TCP接收缓存区),最后服务器就宕机了。所以如果你不能处理那么多请求,请不要循环无限制地调用serverSocket.accept(),否则backlog也无法生效。如果真的请求过多,只会让你的服务器宕机(相信很多人都是这么写,要注意点)

  TcpNoDelay

  禁用纳格算法,将数据立即发送出去。纳格算法是以减少封包传送量来增进TCP/IP网络的效能,当我们调用下面代码,如:

  1. Socket socket = new Socket();    
  2. socket.connect(new InetSocketAddress(host, 8000));    
  3. InputStream in = socket.getInputStream();    
  4. OutputStream out = socket.getOutputStream();    
  5. String head = "hello ";    
  6. String body = "world\r\n";    
  7. out.write(head.getBytes());    
  8. out.write(body.getBytes());

  我们发送了hello,当hello没有收到ack确认(TCP是可靠连接,发送的每一个数据都要收到对方的一个ack确认,否则就要重发)的时候,根据纳格算法,world不会立马发送,会等待,要么等到ack确认(最多等100ms对方会发过来的),要么等到TCP缓冲区内容>=MSS,很明显这里没有机会,我们写了world后再也没有写数据了,所以只能等到hello的ack我们才会发送world,除非我们禁用纳格算法,数据就会立即发送了。

  SoLinger

  当我们调用socket.close()返回时,socket已经write的数据未必已经发送到对方了,例如

  1. Socket socket = new Socket();    
  2. socket.connect(new InetSocketAddress(host, 8000));    
  3. InputStream in = socket.getInputStream();    
  4. OutputStream out = socket.getOutputStream();    
  5. String head = "hello ";    
  6. String body = "world\r\n";    
  7. out.write(head.getBytes());    
  8. out.write(body.getBytes());   
  9. socket.close();

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号