首先点一下TCP协议和Socket各个API函数的关系:
服务端只有bind()没有Listen(),客户端会Connect()成功吗?
- Connect()失败
- bind()操作只是服务端绑定IP:Port(其他进程便无法bind()此IP:Port),并没有监听,lsof -i找不到端口对应的Fd
服务端只有Listen()没有accept(),客户端会Connect()成功吗?
- Connect()成功,且tcpdump有完整的3次握手报文
- Listen()操作后,内核会维护一个监听队列,用于与客户端建立连接(完成3次握手),故客户端能Connect()成功。
服务端accept()会产生网络通讯吗?
- 没有,tcpdump显示没有报文产生
- accept()操作只是从Listen()的监听队列中取出一个连接,并建立一个新Socket用于与客户端通讯,故没有网络通讯产生。
服务端只有Listen()没有accept(),客户端Connect()成功后可以调用write()写数据吗?
- 可以写数据,write()调用返回成功,且tcpdump有完整的请求[PSH]-应答[ACK]报文产生
- 虽然没有accept(),但客户端依然能write()数据,这时数据存储在服务端的TCP缓冲区中,等到进程accept()之后还可以read()到
服务端只有Listen()没有accept(),客户端连接能正常断开吗?
- 不能,客户端调用close()之后,tcpdump显示没有完整的4次握手断开报文,只有前2个报文[FIN]和[ACK]
- 由于服务端没有accept()取出连接fd调用close(),对于服务端没有调用close()的连接,由上图可知客户端的TCP连接会停留在FIN_WAIT_2状态,一直占用客户端资源到FIN_WAIT_2状态超时
- 故Socket编程最后加上close()是必要的编程规范
TCP协议和SocketAPI的几个小问题,布布扣,bubuko.com
TCP协议和SocketAPI的几个小问题
原文:http://blog.csdn.net/yyyiran/article/details/22741711