java socket重要参数讲解
Java Socket的api可能很多人会用,但是Java Socket的参数可能很多人都不知道用来干嘛的,甚至都不知道有这些参数。
backlog用于ServerSocket,配置ServerSocket的最大客户端等待队列。等待队列的意思,先看下面代码
![复制代码](http://common.cnblogs.com/images/copycode.gif)
public class Main { public static void main(String[] args) throws Exception { int port = 8999; int backlog = 2; ServerSocket serverSocket = new ServerSocket(port, backlog); Socket clientSock = serverSocket.accept(); System.out.println("revcive from " + clientSock.getPort()); while (true) { byte buf[] = new byte[1024]; int len = clientSock.getInputStream().read(buf); System.out.println(new String(buf, 0, len)); }
![复制代码](http://common.cnblogs.com/images/copycode.gif)
这段测试代码在第一次处理一个客户端时,就不会处理第二个客户端,所以除了第一个客户端,其他客户端就是等待队列了。所以这个服务器最多可以同时连接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网络的效能,当我们调用下面代码,如:
![复制代码](http://common.cnblogs.com/images/copycode.gif)
Socket socket = new Socket(); socket.connect(new InetSocketAddress(host, 8000)); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); String head = "hello "; String body = "world\r\n"; out.write(head.getBytes()); out.write(body.getBytes());
![复制代码](http://common.cnblogs.com/images/copycode.gif)
我们发送了hello,当hello没有收到ack确认(TCP是可靠连接,发送的每一个数据都要收到对方的一个ack确认,否则就要重发)的时候,根据纳格算法,world不会立马发送,会等待,要么等到ack确认(最多等100ms对方会发过来的),要么等到TCP缓冲区内容 =MSS,很明显这里没有机会,我们写了world后再也没有写数据了,所以只能等到hello的ack我们才会发送world,除非我们禁用纳格算法,数据就会立即发送了。
纳格算法参考:http://zh.wikipedia.org/wiki/%E7%B4%8D%E6%A0%BC%E7%AE%97%E6%B3%95
另外有一篇讲解纳格算法和delay ack的文章(挺不错的):http://blog.csdn.net/frankggyy/article/details/6624401
SoLinger当我们调用socket.close()返回时,socket已经write的数据未必已经发送到对方了,例如
![复制代码](http://common.cnblogs.com/images/copycode.gif)
Socket socket = new Socket(); socket.connect(new InetSocketAddress(host, 8000)); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); String head = "hello "; String body = "world\r\n"; out.write(head.getBytes()); out.write(body.getBytes()); socket.close();
![复制代码](http://common.cnblogs.com/images/copycode.gif)
这里调用了socket.close()返回时,hello和world未必已经成功发送到对方了,如果我们设置了linger而不小于0,如:
bool on = true; int linger = 100; socket.setSoLinger(boolean on, int linger) ...... socket.close();
那么close会等到发送的数据已经确认了才返回。但是如果对方宕机,超时,那么会根据linger设定的时间返回。
UrgentData和OOBInline
TCP的紧急指针,一般都不建议使用,而且不同的TCP/IP实现,也不同,一般说如果你有紧急数据宁愿再建立一个新的TCP/IP连接发送数据,让对方紧急处理。
所以这两个参数,你们可以忽略吧,想知道更多的,自己查下资料。
SoTimeout设置socket调用InputStream读数据的超时时间,以毫秒为单位,如果超过这个时候,会抛出java.net.SocketTimeoutException。
KeepAlive
keepalive不是说TCP的常连接,当我们作为服务端,一个客户端连接上来,如果设置了keeplive为true,当对方没有发送任何数据过来,超过一个时间(看系统内核参数配置),那么我们这边会发送一个ack探测包发到对方,探测双方的TCP/IP连接是否有效(对方可能断点,断网),在Linux好像这个时间是75秒。如果不设置,那么客户端宕机时,服务器永远也不知道客户端宕机了,仍然保存这个失效的连接。
SendBufferSize和ReceiveBufferSizeTCP发送缓存区和接收缓存区,默认是8192,一般情况下足够了,而且就算你增加了发送缓存区,对方没有增加它对应的接收缓冲,那么在TCP三握手时,最后确定的最大发送窗口还是双方最小的那个缓冲区,就算你无视,发了更多的数据,那么多出来的数据也会被丢弃。除非双方都协商好。
以上的参数都是比较重要的Java Socket参数了,其他就不另外说明了。
原文链接:[http://wely.iteye.com/blog/2360392]
【Java】网络编程--Socket与TCP网络通信编程 文章目录 1 Socket 2 TCP网络通信编程 2.1 TCP字节流编程 2.1.1 案例:客户端发送数据,服务端接收并显示 2.1.2 案例进阶:双向通信 2.2 TCP字符流编程 2.3 网络上传文件
java网络编程(2)socket通信案例(TCP和UDP) java生下来一开始就是为了计算机之间的通信,因此这篇文章也将开始介绍一下java使用socket进行计算机之间的通信,在上一篇文章中已经对网络通信方面的基础知识进行了总结,这篇文章将通过代码案例来解释说明。
使用Java Socket手撸一个http服务器 作为一个java后端,提供http服务可以说是基本技能之一了,但是你真的了解http协议么?你知道知道如何手撸一个http服务器么?tomcat的底层是怎么支持http服务的呢?大名鼎鼎的Servlet又是什么东西呢,该怎么使用呢? 在初学java时,socket编程是逃不掉的一章;虽然在实际业务项目中,使用这个的可能性基本为0,本篇博文将主要介绍如何使用socket来实现一个简单的http服务器功能,提供常见的get/post请求支持,并再此过程中了解下http协议
相关文章
- java 程序员 和 三八女神节有什么神秘的关系,你晓得吗? 用Java 给女神绘制一张贺卡你会吗?
- Java多线程系列—final的各种用法与意义(07)
- Java 6 JVM参数选项大全(中文版)
- Java Invoked OOM-Killer - OOM不一定是来自于java heap
- java实现定时任务的三种方法
- 34 异常机制 异常体系结构 Java把异常当做对象来处理 并定义一个基类java.lang.Throwable作为所有异常的超类 Error Exception
- 第30节:Java基础-内部类
- 第二十七节:Java基础面向对象-静态,单例模式,继承详情知识点
- 第七节:详细讲解Java中的日期,java.util.date
- Java 获取Url中的参数Map
- Java 通过JDBC查询数据库表结构(字段名称,类型,长度等)
- java数组复制的几种常见用法
- JAVA好书之《深入理解Java虚拟机》
- Java升级那么快,多个版本如何灵活切换和管理?
- java中不定参数的使用
- Java学习-050-AES256 之 java.security.InvalidKeyException: Illegal key size or default parameters 解决方法
- Java学习-018-EXCEL 文件写入实例源代码
- java中文排序
- Java_类似java.lang.VerifyError: Expecting a stackmap frame at branch target 22 in method的解决方法
- 浅析Java如何使用docker-java库操作DockerAPI
- Java之可变参数方法使用说明
- java中导出
- Redmonk发布Java框架流行度调研结果
- 如何提高 Java 中锁的性能
- 【JAVA】2.输入一个复杂链表(每个节点中有节点值, 以及两个指针,一个指向下一个节点, 另一个特殊指针指向任意一个节点), 返回结果为复制后复杂链表的head。 (注意,输出结果中请不要返回参数中
- Java全栈系列笔记
- ajax 调用 java webapi 多个参数(二)
- 深入理解Java:类加载机制及反射
- C++/C, Java学习资料
- Springboot项目java -jar 启动jar包参数详解