??xml version="1.0" encoding="utf-8" standalone="yes"?>99国产麻豆精品,日韩久久一区,亚洲2区在线http://www.aygfsteel.com/zhvfeng/category/45711.htmlzh-cnWed, 28 Jul 2010 05:34:32 GMTWed, 28 Jul 2010 05:34:32 GMT60Socket Programming Considerations (2)http://www.aygfsteel.com/zhvfeng/archive/2010/07/28/327281.html天快黑了天快黑了Wed, 28 Jul 2010 01:23:00 GMThttp://www.aygfsteel.com/zhvfeng/archive/2010/07/28/327281.htmlhttp://www.aygfsteel.com/zhvfeng/comments/327281.htmlhttp://www.aygfsteel.com/zhvfeng/archive/2010/07/28/327281.html#Feedback0http://www.aygfsteel.com/zhvfeng/comments/commentRss/327281.htmlhttp://www.aygfsteel.com/zhvfeng/services/trackbacks/327281.html1.       Socket ack (acknowledgement)

Socket ack是指?/span>socket接收到数据之后,发送一?/span>ack字符?/span>(比如$ACK)l?/span>socket发送方。这Psocket发送方可以Ҏ是否收到?/span>ack判断Ҏ是否收到了数据?/span>

Socket ack是显C的在应用程序中加入的一U通讯协议。如果不使用ackQ在socket通讯中,可能会丢失数据?/span>

比如Q?/span>socket client要连l的l?/span>socket server发?/span>100条消息。如果我们在server收到W?/span>50条消息的时候,kill?/span>server。那么查?/span>client端发送的logQ可?/span>client端成功发送了51条。只有当client端发送第52条消息的时候才遇到异常。这L51条消息就丢失了?/span>

所以ؓ了确保数据传输的准确性,我们可以引入ack协议。有时我们不仅要保server不但收到了数据,而且q要保证server成功处理了数据。这Ӟ可以{?/span>server成功处理完数据之后,再给client?/span>ack?/span>

2.       Socket Keep Alive

Socketq接像数据库q接一P属于重量型资源。如果我们频J的创徏socket、发?/span>/接收数据、关?/span>socketQ那么会有很大一部分旉费?/span>socket的创建和关闭上?/span>

所以,如果我们l常需要与同一?/span>socket地址发?/span>/接收数据Ӟ应该考虑只创Z?/span>socketQ然后一直用这?/span>socket对象发?/span>/接收数据?/span>

3.       Heartbeat

通常Q我们会讄socket?/span>receive timeout。这P如果我们一直打开着socket (keep alive)Q?/span> 而很长时间又没有数据通讯Q?/span>socket接收方就?/span>timeoutQ最l导致打开的连接坏掉?/span>

如果很长旉没有数据通讯Q防火墙或代理服务器也可能会关闭打开?/span>socketq接?/span>

所以ؓ了保证打开?/span>socketq接一直可用,如果一D|间没有数据进行通讯Q或指定一个时间间隔)Q我们可以显C的发送一?/span>heartbeat消息(比如: $HRT)l对方,从而保证连接不会被异常关闭?/span>

4.       Socket Close

每一个socket对象会持有一个socket descriptor (其实是file descriptor)Q操作系l对于socket descriptor有一个最大限?/span>。因此当socket不再使用Ӟ一定要记得关闭Q即?/span>socketq接p|或出现异常,只要socket对象不ؓnullQ一定要记得关闭?/span>

下面图显CZQ当socket关闭Ӟsocket的状态变?/span>(socket状态可以通过netstat命o查看)。更详细的解释,可以google一下?br />

当主动一方调?/span>close(先调?/span>close)时的状态变?/span>:

ESTABLISHED -> FIN_WAIT_1-> FIN_WAIT_2 -> TIME_WAIT -> CLOSED

当被动一方调?/span>close(后调?/span>close)时的状态变?/span>:

ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED

通常Q?/span>TIME_WAIT 是正常状态,q一D|?/span>(2MSL, 1?/span>4分钟)׃自动消失.

我们需要特别注?/span>CLOSE_WAIT 状态:

1Q?span style="font: 7pt 'Times New Roman'">   如果很长旉才消失,表明socket server处理太慢Q很?/span>client已经q接?/span>serverQ发送完数据q?/span>close了?/span>

2Q?span style="font: 7pt 'Times New Roman'">   如果一直也不消失,表明?/span>socket没有正常close (Ҏ已经close?/span>)

5.       SO_REUSEADDR Option

?/span>socketd调用close的时候,从上面可以知道,它最l会q入TIME_WAIT 状态,需要过1?/span>4分钟Q才能完?/span>close?/span>

?/span>socket处于TIME_WAIT 状态时Q它仍然占用正在使用?/span>IP/PORT。这P如果我们的程?/span>(比如socket server)使用了一个固定的IP/PORTQ当socket处于TIME_WAIT 状态时Q程序将不能立即重启Q会出现端口占用错误?/span>

Socket提供了一?/span>setReuseAddress()ҎQ可以设|当socket处于TIME_WAIT 状态时Q是否允许其它进E绑定这个端口?/span>

如果我们正在开?/span>socket serverQ一定要记得调用ServerSocket.setReuseAddress(true).

Client socket也有q个ҎQ而且有时可能需要指?/span>clientq接server时所使用的本?/span>IP/PORT(一般不用指明,pȝ会随机选择一?/span>PORT)。但实际试Q在client socket上设|这个方法在Windows?/span>Solaris下ƈ不v作用。当socket处于TIME_WAIT 状态时Q重?/span>client仍然出现端口占用错误。上|搜索了很长旉Q很多h都碰Cq个问题Q可能是操作pȝ底层socket实现问题。因为测试?/span>C语言开发的socket clientQ同样也有这个错误。有LINUX下好用,q有是可以试修改tcp_time_wait_interval来减?/span>TIME_WAIT{待旉



天快黑了 2010-07-28 09:23 发表评论
]]>
Socket Programming Considerations (1)http://www.aygfsteel.com/zhvfeng/archive/2010/07/26/327114.html天快黑了天快黑了Mon, 26 Jul 2010 01:31:00 GMThttp://www.aygfsteel.com/zhvfeng/archive/2010/07/26/327114.htmlhttp://www.aygfsteel.com/zhvfeng/comments/327114.htmlhttp://www.aygfsteel.com/zhvfeng/archive/2010/07/26/327114.html#Feedback1http://www.aygfsteel.com/zhvfeng/comments/commentRss/327114.htmlhttp://www.aygfsteel.com/zhvfeng/services/trackbacks/327114.html
最q一直在做SocketE序Q这里把一些SocketE序的注意事Ҏȝ一下。今天先说说Socket中的TimeoutQ其它的下次补全?br />

1.       Socket Timeout

?/span>SocketE序的时候需要注意设|下面的timeoutQ避免对Ҏ有响应的时候,DSocketE序挂v或等待时间过?/span>

1.1         Accept Timeout

Accept timeout 仅对ServerSocket有用?/span>ServerSocket 使用accept()Ҏ来监听客LSocket的连接?/span>

默认Q?/span>ServerSocket.accept() Ҏ会一直阻塞直到有客户端来q接。通常Q我们不需要设|?/span>accept timeout.

但有时候特D情况,q是要考虑讄accept timeout.

比如: E序Al程?/span>B发了一?/span>JMS消息Q然后程?/span>A启动一?/span>Socket ServerQ想通过socket{待接收E序B的返回消息。如果不讄accept timeout, q且E序B因ؓ某些原因一直不能连?/span>Socket ServerQ最l会DE序A挂v?/span>

Accept Timeout可以q样讄Q?/span>

ServerSocket serverSocket = new ServerSocket(5555);

serverSocket.setSoTimeout(5000); // in milliseconds

while (true) {

    Socket socket = serverSocket.accept();

        …

}

1.2         Connect Timeout

?/span>Client端连?/span>Server端的时候,可以指定Connect Timeout

如果没有指定Q会使用操作pȝ的默认?/span>:

OS

Default TCP timeout

BSD

75 seconds

Linux

189 seconds

Solaris

225 seconds

Windows XP

21 seconds

Connect Timeout可以q样讄Q?/span>

SocketAddress socketAddress = new InetSocketAddress(host, port);

socket = new Socket();

socket.connect(socketAddress, connectTimeout);

1.3         Receive Timeout

?/span>socket从另一Ҏ收数据时Q可以设|?/span>Receive Timeout

默认没有timeoutQ?/span>socket会一直阻塞直到有数据可读取?/span>

Receive Timeout可以q样讄Q?/span>

Socket socket = new Socket(host, port);

socket.setSoTimeout(timeout);

1.4         Send Timeout

Send Timeout?/span>socketl另一方发送数据时使用的?/span>

不过Java里没有办法设|?/span>Send Timeout.

当然Q?/span>socket发送数据的时候,会首先发送到本机OS的一?/span>buffer内。一般只要一ơ发送的数据不是很大Q即使对Ҏh暂时不能接收数据Q也不会D发送方挂v?/span>




天快黑了 2010-07-26 09:31 发表评论
]]>
վ֩ģ壺 ƽ| ϰˮ| | | ͷ| | | | | | Ͷ| | | ϽϽ| Դ| ÷ӿ| ϼ| | | | Զ| | ȫ| Ͼ| | ƺ| ³ɽ| | | ƺ| ˳ƽ| | | | | ͼ| | ˮ| | | ߱|