(1) 三次握手: 建立一个TCP连接,必须经历三次握手过程,其中发送第一个SYN的一端将执行主动打开,接收这个SYN并发回下一个SYN的另一端执行被动打开。 (2) 四次释放: 要释放一个TCP连接,需要通过四次握手过程,这是由TCP的半关闭特性造成的,因为TCP连接时全双工的,因此,需要TCP两端要单独执行关闭。值得 注意的是,主动关闭的一端在发送FIN之后,依然还能正常接收对方的数据,只是通知对方它已经没有数据需要发送了,同理,被动关闭的一端在收到FIN之 后,仍然可以发送数据,直到它自身同样发出FIN之后,才停止发送数据。 (3) TCP连接的超时问题: 完成一个TCP连接,中间涉及到一个超时的问题,大多数伯克利系统的超时时限为75s,Solaris9的超时时限为240s,因此,一般认为是在75-240之间。 【引申】在具体的实现中,如何由用户自己去完成设置socket连接超时时间? 【解决方法】目前实现socket超时连接主要是通过select来完成的。具体步骤如下: ◆ 建立socket ◆ 将socket设置为非阻塞模式(若是阻塞模式,那么时间设置就毫无意义) ◆ 调用connect去进行连接 ◆ 使用select检查socket是否可写,并同时判断其结果(为什么是可写?因为需要检测socket是否收到ACK。) ◆ 将socket转化为阻塞模式 (4)TCP的半关闭 www.2cto 所谓“半关闭”,是指连接的一端在结束它的发送之后还能接收到对方发过来的数据的能力。具体表现在,当完成三次握手的双方,其中有一端发出FIN,此时它将进入半关 闭状态,此时它关闭了自身的发送功能,但是它依然可以接收到对方的数据,如对方发过来的ACK消息。那么在实际开发中,是怎么实现的呢? 这牵涉到系统中shutdown和close函数的区别问题。 int shutdown(int s, int how) <sys/socket.h> shutdown是用来终止参数s所指定的socket接口,参数how主要有以下几种情况: how = 0 终止读取操作 how = 1 终止写入操作 how = 2 终止读取和写入操作 返回的errorcode可能有: EBADF /* Bad file descriptor */ ENOTSOCK /* Socket operation on non-socket */ ENOTCONN /* Socket is not connected */ 【引用】 Big difference between shutdown and close on a socket is thebehavior when the socket is shared by other processes.A shutdown() affects all copies of the socket whileclose() affects only the file descriptor in one process. Even if you close() a TCP socket, it won't necessarily beimmediately reusable anyway, since it will be in a TIME_WAITstate while the OS makes sure there's no outstandingpackets that might get confused as new information if you were to immediatelyreuse that socket for something else. 【注意】 当shutdown关闭读取部分时,则会丢掉接收缓冲区中的任何数据,并关闭该端的连接,若是关闭写入部分,TCP则会发送剩余的数据,然后终止连接的写入端。 4. TCP的状态变迁图: