Posix API与网络协议栈
网络编程需要的函数
客户端: socket,bind(optional),connect,recv,send,close
服务器端:socket,bind,listen,accept,recv,send,close
一条网络连接的标志:五元组:(remoteip,remoteport,localip,localport,proto);
socket:在内核创建一个tcb(tcp control block), 并向用户进程返回这个tcb的文件描述符。
bind:把某个ip、port和tcb绑定。
connect:发起tcp连接,启动三次握手。可以阻塞,也可以非阻塞;成功返回0,失败返回-1。
listen:将一个主动tcb转换为被动tcb,使它能接收connect连接。第二个参数在Linux下的含义是全连接队列
accept:从被动tcb的全连接队列中返回已连接好的tcp文件描述符。
recv:从tcb缓冲区向用户进程缓冲区copy数据。当无法copy时,如果是阻塞模式,recv会阻塞用户进程,直到recv顺利将数据拷贝到用户进程缓冲区为止;如果是非阻塞模式,recv会直接返回-1。如果另一端连接被关闭,recv会返回0。
send:从用户进程缓冲区向tcb缓冲区copy数据。当无法copy时,如果是阻塞模式,send会阻塞用户进程,知道send顺利将数据拷贝到tcb缓冲区为止;如果是非阻塞模式,send会直接返回-1。
close:发起tcp关闭,启动四次握手。四次握手的完成,需要两边各调用一次close。
TCP状态转换图
可靠传输的工作原理
发送者发送了一系列的连续分组后,就会停止发送,等待接收接收者发送回来的确认报文。如果某些数据分组没有被接收到或者出错,接收者就不会发送这些分组的确认报文。接收者只发送收到的连续分组中最后一个分组的序列的后一个序列。发送者需要将这个序列即其之后的序列全部重传。
TCP连接——三次握手
TCP数据传输
recv, send
recv的作用是将tcb缓冲区的数据拷贝到用户缓冲区中,如果拷贝成功,则表明recv函数执行成功,tcb缓冲区什么时候能将数据准备好,是由内核决定的。
send的作用是将tcb缓冲区中的数据拷贝到用户缓冲区中,什么时候发送,是由内核决定的。
TCP连接的释放——四次挥手
主动断开的一方需要先调用close,内核会向连接方发送连接释放报文,其中FIN = 1,接收方接收后会回复ACK = 1的确认报文。之后等待接收方主动调用close,发送FIN = 1的连接释放报文。当接收方接收到ACK = 1的确认报文后,接收方的TCP连接正式关闭。发送方发送确认报文后,会等待一段时间(大约为2分钟)。这段时间过后,连接就正式关闭了。
TCP连接结束后,TCB被回收。