1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| int socket(int af, int type, int protocol); af 为地址族(Address Family),也就是 IP 地址类型,常用的有 AF_INET 和 AF_INET6。AF 是“Address Family”的简写,INET是“Inetnet”的简写。AF_INET 表示 IPv4 地址,例如 127.0.0.1;AF_INET6 表示 IPv6 地址,例如 1030::C9B4:FF12:48AA:1A2B。 type 为数据传输方式,常用的有 SOCK_STREAM 和 SOCK_DGRAM protocol 表示传输协议,常用的有 IPPROTO_TCP 和 IPPTOTO_UDP
int bind(int sock, struct sockaddr *addr, socklen_t addrlen); int bind(SOCKET sock, const struct sockaddr *addr, int addrlen); sock 为 socket 文件描述符, addr 为 sockaddr 结构体变量的指针, addrlen 为 addr 变量的大小,可由 sizeof() 计算得出。
struct sockaddr_in{ sa_family_t sin_family; uint16_t sin_port; struct in_addr sin_addr; char sin_zero[8]; };
int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen); int connect(SOCKET sock, const struct sockaddr *serv_addr, int addrlen);
让套接字进入被动监听状态,所谓被动监听,是指当没有客户端请求时,套接字处于“睡眠”状态,只有当接收到客户端请求时,套接字才会被“唤醒”来响应请求。 int listen(int sock, int backlog); int listen(SOCKET sock, int backlog); sock 为需要进入监听状态的套接字 backlog 为请求队列的最大长度
请求队列 当套接字正在处理客户端请求时,如果有新的请求进来,套接字是没法处理的,只能把它放进缓冲区,待当前请求处理完毕后,再从缓冲区中读取出来处理。如果不断有新的请求进来,它们就按照先后顺序在缓冲区中排队,直到缓冲区满。这个缓冲区,就称为请求队列(Request Queue)。 缓冲区的长度(能存放多少个客户端请求)可以通过 listen() 函数的 backlog 参数指定,但究竟为多少并没有什么标准,可以根据你的需求来定,并发量小的话可以是10或者20。 如果将 backlog 的值设置为 SOMAXCONN,就由系统来决定请求队列长度,这个值一般比较大,可能是几百,或者更多。 当请求队列满时,就不再接收新的请求,对于 Linux,客户端会收到 ECONNREFUSED 错误,对于 Windows,客户端会收到 WSAECONNREFUSED 错误。
int accept(int sock, struct sockaddr *addr, socklen_t *addrlen); SOCKET accept(SOCKET sock, struct sockaddr *addr, int *addrlen); 返回一个新的套接字来和客户端通信,addr 保存了客户端的IP地址和端口号,而 sock 是服务器端的套接字
Linux下的数据接收和发送
会将缓冲区 buf 中的 nbytes 个字节写入文件 fd,成功则返回写入的字节数,失败则返回 -1。 ssize_t write(int fd, const void *buf, size_t nbytes); fd 为要写入的文件的描述符,buf 为要写入的数据的缓冲区地址,nbytes 为要写入的数据的字节数。
会从 fd 文件中读取 nbytes 个字节并保存到缓冲区 buf,成功则返回读取到的字节数(但遇到文件结尾则返回0),失败则返回 -1。 ssize_t read(int fd, void *buf, size_t nbytes);
Windows下的数据接收和发送 int send(SOCKET sock, const char *buf, int len, int flags); int recv(SOCKET sock, char *buf, int len, int flags);
|