Posix API
本文创建于
2024-12-12;修改于2024-12-13;
一、Linux 网络IO API
Posix API 网络通信相关函数:
TCP 状态迁移图:
二、用于建立连接的API
socket
# man socket
# desc: socket - create an endpoint for communication
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
一个 socket 套接字由两部分组成,分别是 文件描述符 fd 和 TCP控制块 tcp control block;理所应当的,socket 函数就是负责处理这两部分的。
- fd: 文件描述符,int 类型,系统递增分配,底层为 bitmap(位图),通过置0置1来判断某个fd是否已经分配了;
bind
# man bind:
# desc: bind - bind a name to a socket
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
bind 函数用于将我们设置的 ip地址 和 port端口设置进 socket 分配的 tcb(TCP控制块)内,以备后续连接。
注:对于 client 来说,bind 不是必须的,如果没有主动绑定到端口的话,后期系统会自动为其分配随机端口。
listern
# man listen
# desc: listen - listen for connections on a socket
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd, int backlog);
listen 函数主要职责就是,将套接字中tcb内的状态设置为监听状态;为 tcb 分配一个全连接队列,以及一个半连接队列;
- tcb -> status = TCP_STATUS_LISTEN
- tcb -> syn_queue
- tcb -> qccept_queue
listen状态后,才能够建立TCP连接,接下来就是TCP建立一个连接的流程;
accept
# man accept
# desc: accept, accept4 - accept a connection on a socket
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept 函数的工作分为两部分,分配fd给对应的client,把 fd 和 tcb 做映射;
三、用于传输数据的API
recv
# man recv
desc: recv, recvfrom, recvmsg - receive a message from a socket
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
send
# man send
desc: send, sendto, sendmsg - send a message on a socket
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
四、断开连接
close
# man close
desc: close - close a file descriptor
#include <unistd.h>
int close(int fd);
close 函数的工作大概是:
- 关闭一个fd;
- 之后向被动方发送一个
fin 字段置1; 数据长度为0的tcp报文 - 被动发 recv 该报文后发现数据段长度为0,得知这是要求关闭的一个tcp报文,会回发
ack 字段置1的tcp报文
TCP 四次挥手流程:
注意:在断开连接时没有客户端与服务端的概念,只有主动方与被动方;