最近在开发一款多线程音乐下载播放器的服务端.
包括tcp应用服务器和服务容器的代码.
刚开始进行压力测试的时候频繁出现Connection reset by peer异常,
并且成功的连接数不超过50个.
google一下发现
出现Connection reset by peer比较常见的原因是:
服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;
.连接被防火樯或proxy中断,或防火墙和代理设置不当。
对于第一种原因,
回想起tcp/ip详解第一卷协议中提到过:
bsd的socket的tcp连接队列的默认长度是5,
backlog 用于在TCP层接收链接的缓冲池的最大个数,这个个数可在应用层中的listen函数里设置,当客户链接请求大于这个个数(缓冲池满),其它的未进入链接缓冲池的客户端在tcp层上tcp模块会自动重新链接,直到超时(大约57秒后)
我们的应用层的链接完成是要从tcp层的链接缓冲池中移出一个(accept函数实现)
因此我在本机测试的时候,连接数超过50就报Connection reset by peer.
是因为连接数限制,操作系统(当前系统为win2k.)把超出的连接丢弃的原因.
我兴冲冲地把serversocket的backlog设置为200,可以支持
200个线程每休息2s发送一次请求,请求的等待时间为5s.
也就是大约每7s进行一次请求应答.
计算下来,1s能进行30次请求应答.
另外记录一下SO_LINGER
3.2 How do I control the amount of time a socket will linger before resetting?
When a socket wishes to terminate a connection it can "linger", allowing unsent data to be transmitted, or it can "reset" which means that all unsent data will be lost. You can explicitly set a delay before a reset is sent, giving more time for data to be read, or you can specify a delay of zero, meaning a reset will be sent as the java.net.Socket.close() method is invoked.
The socket option SO_LINGER controls whether a connection will be aborted, and if so, the linger delay. Use the java.net.Socket.setSoLinger method, which accepts as parameters a boolean and an int. The boolean flag will activate/deactivate the SO_LINGER option, and the int will control the delay time.
摘自 http://www.davidreilly.com/java/java_network_programming/