Unix网络编程 学习笔记 1-4章

来源:互联网 发布:淘宝小二介入规则 编辑:程序博客网 时间:2024/05/22 00:47

记录一下网络编程的重点和难点


第二章 传输层 TCP UDP

2.6 TCP连接的建立和终止

2.6.1 三路握手


1. 服务器必须准备好接受外来的连接。通常通过调用socket、bind、listen这3个函数来完成,我们称之为被动打开。

2. 客户通过调用connect发起主动打开。这导致客户TCP发送一个SYN分节,它告诉服务器客户将在(待建立的)连接中发送的数据的初始序列号。通常SYN分节不携带数据,其所在IP数据只含有一个IP首部、一个TCP首部及可能有的TCP选项。

3. 服务器必须确认(ACK)客户的SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器在单个分节中发送SYN和对客户的SYN的ACK。

4. 客户必须确认服务器的SYN。


2.6.3 TCP连接终止

四次挥手


1. 某个应用进程首先调用close,我们称该端执行主动关闭。该端的TCP于是发送一个FIN分节,表示数据发送完毕。

2. 接收到这个FIN的对端执行被动关闭。这个FIN由TCP确认。它的接收也作为一个文件结束符传递给接收端应用进程(放在已排队等候该应用进程接收的任何其他数据之后),因为FIN的接收意味着接收端应用进程在响应连接上再无额外数据可接收。

3. 一段时间后,接收到这个文件结束符的应用进程将调用close关闭他的套接字。这导致他的TCP也发送一个FIN。

4. 接收这个最终的FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。

2.6.4 TCP状态转换图


2.10 TCP端口号和并发服务器


TCP是通过一对socket(socket pair)来区分socket通讯的,可以这么理解,socket = ip + port,socket pair = client socket + server socket。 所以,当使用一个监听器监听时,一旦accept到一个connect后,可以,将这个socket交给一个线程或进程执行任务,在线程中执行这个任务的同时,主线程仍然可以accept其他client socket的链接。因为,每个tcp connection的socket pair中的client socket是不一样的,所以tcp是可以区分这些连接。下面这个举个列子,如下图所示,


此时,客户CS1=206.168.112.219:1500,发起了连接,连接到服务器socket,SS = 12.106.32.254:21。连接后服务器fork一个子进程,用来处理CS1的相关操作,这时客户2也发起了到服务器的连接


CS2 = 206.168.112.219:1501,此时服务器再fork一个进程处理该链接,此时CS1和SS的链接仍然存在,并且SS还可以监听其他链接。

通过以上的描述,你可以知道socket只有在accept的时候会block,accept后只要fork或采用多线程,处理请求,就可以继续监听其他请求,也就是说,监听socket和accept之后的socket是可以同时存在,互相不影响的。

这时因为TCP是根据socket pair来区分连接的,而不是根据单独的socket

2.11 缓存大小和限制


对于同步的socket(blocking socket),write函数的内部如何操作?

write函数会将应用程序buffer中的数据写到Tcp buffer,这里会发生一次数据copy,因为tcp需要得到这份数据进行重传。TCP buffer是有大小的,可以通过SO_SNDBUF来设置,如果满了却没有装满应用程序的数据,那么应用程序进程就会sleep,也就是堵塞了,直到应用程序的数据全部copy到tcp buffer中,write程序才会返回(这里针对默认的blocking socket)。所以,可以想一下,如果应用程序每次都传超过SO_SNDBUF的数据,那么每次至少会sleep一次,效率会大打折扣。而且,write返回后,并不意味者客户端接收到了所有数据,他只表明应用程序中的数据全部copy到tcp buffer中,仅此而已,接下来由tcp负责将数据发送给客户端。下图是tcp buffer和应用程序buffer的示意图:


0 0
原创粉丝点击