Java Socket的api可能很多人会用但是Java Socket的参数可能很多人都不知道用来干嘛的甚至都不知道有这些参数
backlog
用于ServerSocket配置ServerSocket的最大客户端等待队列等待队列的意思先看下面代码
public class Main { public static void main(String[] args) throws Exception { int port = int backlog = ServerSocket serverSocket = new ServerSocket(port backlog)Socket clientSock = serverSocketaccept()Systemoutprintln(revcive from + clientSockgetPort())while (true) { byte buf[] = new byte[]int len = clientSockgetInputStream()read(buf)Systemoutprintln(new String(buf len))}这段测试代码在第一次处理一个客户端时就不会处理第二个客户端所以除了第一个客户端其他客户端就是等待队列了所以这个服务器最多可以同时连接个客户端其中个等待队列大家可以telnet localhost 测试下
这个参数设置为表示无限制默认是个最大等待队列如果设置无限制那么你要小心了如果你服务器无法处理那么多连接那么当很多客户端连到你的服务器时每一个TCP连接都会占用服务器的内存最后会让服务器崩溃的
另外就算你设置了backlog为如果你的代码中是一直Socket clientSock = serverSocketaccept()假设我们的机器最多可以同时处理个请求总共有个线程在运行然后你把在个线程的线程池处理clientSock不能处理的clientSock就排队最后clientSock越来越多也意味着TCP连接越来越多也意味着我们的服务器的内存使用越来越高(客户端连接进程肯定会发送数据过来数据会保存到服务器端的TCP接收缓存区)最后服务器就宕机了所以如果你不能处理那么多请求请不要循环无限制地调用serverSocketaccept()否则backlog也无法生效如果真的请求过多只会让你的服务器宕机(相信很多人都是这么写要注意点)
TcpNoDelay
禁用纳格算法将数据立即发送出去纳格算法是以减少封包传送量来增进TCP/IP网络的效能当我们调用下面代码如
Socket socket = new Socket()nnect(new InetSocketAddress(host ))InputStream in = socketgetInputStream()OutputStream out = socketgetOutputStream()String head = hello String body = world\r\noutwrite(headgetBytes())outwrite(bodygetBytes())我们发送了hello当hello没有收到ack确认(TCP是可靠连接发送的每一个数据都要收到对方的一个ack确认否则就要重发)的时候根据纳格算法world不会立马发送会等待要么等到ack确认(最多等ms对方会发过来的)要么等到TCP缓沖区内容>=MSS很明显这里没有机会我们写了world后再也没有写数据了所以只能等到hello的ack我们才会发送world除非我们禁用纳格算法数据就会立即发送了
SoLinger
当我们调用socketclose()返回时socket已经write的数据未必已经发送到对方了例如
Socket socket = new Socket()nnect(new InetSocketAddress(host ))InputStream in = socketgetInputStream()OutputStream out = socketgetOutputStream()String head = hello String body = world\r\noutwrite(headgetBytes())outwrite(bodygetBytes())socketclose()
这里调用了socketclose()返回时hello和world未必已经成功发送到对方了如果我们设置了linger而不小于如
bool on = trueint linger = ……
socketsetSoLinger(boolean on int linger)
……
socketclose()那么close会等到发送的数据已经确认了才返回但是如果对方宕机超时那么会根据linger设定的时间返回
UrgentData和OOBInline
TCP的紧急指针一般都不建议使用而且不同的TCP/IP实现也不同一般说如果你有紧急数据宁愿再建立一个新的TCP/IP连接发送数据让对方紧急处理
所以这两个参数你们可以忽略吧想知道更多的自己查下资料
SoTimeout
设置socket调用InputStream读数据的超时时间以毫秒为单位如果超过这个时候会抛出SocketTimeoutException
KeepAlive
keepalive不是说TCP的常连接当我们作为服务端一个客户端连接上来如果设置了keeplive为true当对方没有发送任何数据过来超过一个时间(看系统内核参数配置)那么我们这边会发送一个ack探测包发到对方探测双方的TCP/IP连接是否有效(对方可能断点断网)在Linux好像这个时间是秒如果不设置那么客户端宕机时服务器永远也不知道客户端宕机了仍然保存这个失效的连接
SendBufferSize和ReceiveBufferSize
TCP发送缓存区和接收缓存区默认是一般情况下足够了而且就算你增加了发送缓存区对方没有增加它对应的接收缓沖那么在TCP三握手时最后确定的最大发送窗口还是双方最小的那个缓沖区就算你无视发了更多的数据那么多出来的数据也会被丢弃除非双方都协商好
以上的参数都是比较重要的Java Socket参数了其他就不另外说明了