又是一年七夕节,满街的鲜花情侣,亲亲我我春意盎然的视觉......上周和女票闹别扭,死皮赖脸哄完,吃完饭回来就12点多了,感情这事别扭难免,感谢有你,且行且珍惜。
也刚洗完澡,权当复习吧
在网络层,Socket函数需要制定到底是IPv4还是IPv6,分别对应设置为AF_INET和AF_INET6。另外指定到底是TCP还是UDP。TCP协议是基于数据流的所以设置为SOCK_STREAM,而UDP是基于数据报的,因而设置为SOCK_DGRAM。
TCP的三次握手
建立一个TCP连接时会发生以下情形:
- 服务器必须准备好接受外来的连接。这通常通过调用
socket
bind
listen
这三个函数来完成,我们称之为被动打开 - 客户端通过调用
connect
发起主动打开 - 服务器必须确认客户的SYN,同时自己也的发送一个SYN
- 客户必须确认服务器的SYN

client的初始序列号为J,server的初始序列号为K。ACK中的确认号是发送这个ACK的一段所期待的下一个序列号。因为SYN占据一个字节的序列号空间,所以每一个SYN的ACK的确认号就是下一个序列号加1。类似的,每一个结束的ACK中的确认号是该结束的序列号加1。
基于TCP协议的Socket程序函数调用过程

两端创建了Socket之后,接下来的过程中TCP和UDP稍有不同,TCP
:
TCP的服务器端要先建立一个端口,一般是先调用bind函数,给这个Socket赋予一个IP地址和端口。
端口
:当一个网络包来的时候,内核要通过TCP头里面的这个端口,来找到你这个应用程序,把包给你。
IP地址
:有时候,一台机器会有多个网卡,也就会有多个IP地址,你可以选择监听所有网卡,也可以选择监听一个网卡,这样,只有发给这个网卡的包,才会给你。
当服务端有了IP和端口号,就可以调用函数listen
函数进行监听。在TCP的状态图里有一个listen状态,当调用这个函数之后,服务端就进入了这个状态,这个时候客户端就可以发起连接了。
此处请再次回忆上面👆的TCP三次握手的流程图
在内核中,为每个Socket维护两个队列。一个是已经建立了链接的队列,这个时候连接三次握手已经完毕,处于established状态;一个是还没有完全建立连接的队列,这个时候三次握手还没完成,处于syn_rcvd的状态。
接下来,服务器端调用 accept
函数,拿出一个已经完成的连接进行处理。如果还没有完成,就要等着。
在服务器等待的时候,客户端可以通过connect
函数发起连接。现在参数重指明要连接的IP地址和端口号。然后开始发起三次握手。内核会给客户端分配一个临时的端口。一旦握手成功,服务器的accept
就会返回另一个Socket。
连接建立成功之后,双方开始通过read
和write
函数来读写数据,就像往一个文件流里面写东西一样。
基于UDP协议的Socket程序函数调用过程

processon网页在线画图挺不错的,在这贴个链接。
网友评论