网络编程之基本TCP套接口函数解析
在介绍 tcp 套接口相关函数之前,我们先看一下客户端-服务端 tcp 连接全过程。
以上的过程有助于我们理解下面的函数,以下的函数均对应上述过程中的操作
socket 函数
int socket(int family, int type, int protocol);
函数功能:指定期望的通信协议类型,产生一个监听套接字。
参数:
- family:指明协议族,取值可以为AF_INET(IPv4协议)、AF_INET6(IPv6协议)、AF_LOCAL(Unix 域协议)、AF_ROUTE(路由套接口)、AF_KEY(**套接口)
- type:指定套接口类型,取值可以为SOCK_STREAM(字节流套接口)、SOCK_DGRAM(数据包套接口)、SOCK_RAW(原始套接口)
- protocol:一般设置为0,除非用在原始套接口上
返回值:非负描述字
- 非负描述字 – 成功
- -1 – 出错
connect 函数
int connect(int sockfd, const struct sockaddr* servaddr, socklen_t addrlen);
函数功能:用于客户端与 tcp 服务器建立一个连接。
参数:
- sockfd:由socket函数返回的一个套接口描述字
- servaddr:一个指向套接口地址结构的指针
- addrlen:套接口地址结构的大小
返回值:
- 0 – 成功
- -1 – 失败
- ETIMEDOUT:tcp 客户没有收到 SYN 分节的相应
- RST:tcp 服务端在指定端口上没有进程在等待与之连接
- EHOSTUNREACH 或 ENETUNREACH:目的不可达错误
bind 函数
int bind(int sockfd, const struct sockaddr* myaddr, socklen_t addrlen);
函数功能:给套接口分配一个本地协议地址
参数:
- sockfd:由socket函数返回的一个套接口描述符
- myaddr:指向特定协议的地址结构的指针
- addrlen:该地址结构的长度
返回值:
- 0 – 成功
- -1 – 出错
listen 函数
int listen(int sockfd, int backlog);
函数功能:将未连接的套接口(调用socket函数默认是一个调用connect发起连接的客户端套接口)转换为被动套接口(可以理解为服务器端套接口),此外,还规定了内核为此套接口排队的最大连接个数
参数:
- sockfd:由socket函数生成的一个被动套接口
- backlog:没有正式定义过,曾被规定为两个队列(未完成连接队列和已完成连接队列)总和的最大值
返回值:
- 0 – 成功
- -1 – 出错
accept 函数
int accept(int sockfd, struct socketaddr* cliaddr, socklen_t* addrlen);
函数功能:从已完成连接队列头返回下一个已完成连接,若已完成连接队列为空,则进程睡眠
参数:
- sockfd:由socket函数生成的一个套接口描述符
- cliaddr:用来返回连接对方进程的协议地址
- addrlen:调用前,我们设置为cliaddr所指的套接口地址结构的长度,返回时,此整数为内核存在此套接口地址结构内的准确字节数
返回值:
- >0:成功
- -1:出错
fork 函数
pid_t fork(void);
函数功能:派生一个新进程,一次调用,两次返回
返回值:
- 子进程中为 0,父进程中为子进程ID
- -1:出错
close 函数
int close(int sockfd);
函数功能:关闭套接口
参数:
- sockfd:已连接套接口描述符
返回值:
- 0 – 成功
- -1 – 失败
getsockname 函数和 getpeername 函数
int getsockname(int sockfd, struct sockaddr* localaddr, socklen_t* addrlen);
int getpeername(int sockfd, struct sockaddr* peeraddr, socklen_t* addrlen);
函数功能:可以获取由内核赋予该连接的本地IP地址和本地端口号(getsockname)及长度,可以获取当前连接(远程)的客户端的IP地址和端口号(getpeername)
参数:
- sockaddr:
- addrlen:
返回值:
- 0 – 成功
- -1 – 出错