文章

理解Posix API

理解Posix API

理解7个Posix API

POSIX:可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX )。它是一套标准,Unix与Linux和苹果系统的Unix-base都遵循这个标准,话不多说,赶紧进入正题。

socket()

功能:

  1. 分配一个int型的fd。
  2. tcb(tcp控制块),由alloc()创建出来;

bind();

功能:

  1. 将socketfd与ip,port绑定在一起。

    listen():

    下图为TCP状态转移图,listen的过程就是将状态设置为LISTEN,即 tcp -> status = LISTEN tcp -> seqnum = random() tcp -> acknum = random() 以random值开始计数,下一个数据包的seqnum为random+1,acknum同理。 这里设为随机值的原因是以防攻击者推断出已发的数据包的数量

    TCP状态转移图

ss

下图为TCP包,在建立连接的时候(握手)会将ACK与SYN置一,这样就能识别出该数据包是用来握手的。

在这里插入图片描述

1
	具体这个过程在client端发生在connect() 这个函数中,而server端这个过程是在内核协议栈中,代码不可控,是一个被动的过程。tcp是首先在client第一次与server握手的时候,也即listen的时候,将该连接加入半连接队列中;若想要在后续查找到该连接的方法是通过五元组来进行查找。 syn泛洪攻击的时候,可以通过设置listen函数的第二个参数来进行避免,在两个老版本中,分别表示syn queue的大小,这样做可以有效防止泛洪攻击或syn queue与accept queue大小之和,即未被分配fd的tcb数量,现在的版本则是accept queue的大小,这样做则可以有效增加建立连接的数量,增大吞吐量。 客户端与服务端建立连接的过程(三次握手)如下图所示。

在这里插入图片描述

accept():

功能: 分配fd,将fd分配给tcb。 在使用accept函数时,一般是来处理listenfd的情况,且LT时可以做到来一个listenfd接受一个,而在ET的时候则需要用循环来控制:

1
2
3
4
while(1){
	fd = accept();
	if(fd == -1) break;
}

以上四个API实在建立TCP连接的时候进行使用,下面将介绍传输数据的两个API。


send():

send只是通过本机应用传到本机的内核,内核组织好后,若无延迟,由其通过网络传到远程的内核,内核中做的事情是不知道的,是由协议栈决定。

recv():

而在服务器内核接受到数据后调用recv将内核中的数据传到应用中来。

整个流程如下图所示图中mtu代表最大传输单元。

在这里插入图片描述

传输数据的两个API介绍完了,最后还剩下一个断开连接的部分。


close():

功能:fd首先被回收;然后发送fin,在服务端的recv()就会返回0告诉现在要close连接了,然后服务端就也会调用close函数,在这之前会回发一个ack包。后面的流程也同理,服务端回发fin给客户端,客户端也发送ack。这整个流程也可以用上面的TCP状态转移图来理解与分析。

在这里插入图片描述

本文由作者按照 CC BY 4.0 进行授权

热门标签