网站建设自学多长时间,丰收路网站建设,2345浏览器网页版入口,搜狗营销欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 端口复用专栏#xff1a;《Linux从小白到大神》《网络编程》 在前面讲解TCP状态转换中提到过一个2MSL… 欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 端口复用 专栏《Linux从小白到大神》《网络编程》 在前面讲解TCP状态转换中提到过一个2MSL等待时间如果在通信过程中server主动断开连接那么server进程会处于TIME_WAIT状态并等待2MSL的时间此时server进程还没终止端口号port还被该进程占用呢所以当server主动断开连接时如果立即再次启动server就会提示端口已经被使用等待2MSL后才可以再次启动server。请看下图 端口复用常见的用途包括
防止服务器重启时之前绑定的端口还未释放程序突然退出系统但是没有释放端口。
设置端口复用需要用到的API如下
int opt 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)opt, sizeof(opt)); sockfd监听的文件描述符 SOL_SOCKET级别 SO_REUSEADDR也可以用SO_REUSEPORT opt赋值为1表示属性被启用 sizeof(opt)
相关参数设置及含义可在下图中查看 在设置端口复用时需要注意的是必须在绑定端口之前就设置端口复用属性。实际上setsockopt()函数有很多功能设置端口复用只是它的功能之一。
下面是一个设置端口复用的示例
#include stdio.h
#include ctype.h
#include unistd.h
#include stdlib.h
#include sys/types.h
#include sys/stat.h
#include string.h
#include arpa/inet.h
#include sys/socket.h// server
int main(int argc, const char* argv[])
{// 创建监听的套接字int lfd socket(AF_INET, SOCK_STREAM, 0);if(lfd -1){perror(socket error);exit(1);}// 绑定struct sockaddr_in serv_addr;memset(serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family AF_INET;serv_addr.sin_port htons(9999);serv_addr.sin_addr.s_addr htonl(INADDR_ANY); // 本地多有的// 127.0.0.1// inet_pton(AF_INET, 127.0.0.1, serv_addr.sin_addr.s_addr);// 设置端口复用 // 需要在bind函数之前设置int opt 1;setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (void*)opt, sizeof(opt));// 绑定端口int ret bind(lfd, (struct sockaddr*)serv_addr, sizeof(serv_addr));if(ret -1){perror(bind error);exit(1);}// 监听ret listen(lfd, 64);if(ret -1){perror(listen error);exit(1);}// 阻塞等待连接请求 并接受连接请求struct sockaddr_in clien_addr;socklen_t clien_len sizeof(clien_addr);int cfd accept(lfd, (struct sockaddr*)clien_addr, clien_len);if(cfd -1){perror(accetp error);exit(1);}char ipbuf[128];printf(client iP: %s, port: %d\n, inet_ntop(AF_INET, clien_addr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),ntohs(clien_addr.sin_port));char buf[1024] {0};while(1){// read data// int len read(cfd, buf, sizeof(buf));int len recv(cfd, buf, sizeof(buf), 0);if(len -1){perror(recv error);exit(1);}else if(len 0){printf(客户端已经断开连接。。。\n);break;}printf(read buf %s\n, buf);// 小写转大写for(int i0; ilen; i){buf[i] toupper(buf[i]);}printf(after buf %s\n, buf);// 大写串发给客户端// write(cfd, buf, strlen(buf)1);ret send(cfd, buf, strlen(buf)1, 0);if(ret -1){perror(send error);exit(1);}}close(cfd);close(lfd);return 0;
}