端口复用详解

2、多线程并发服务器的步骤
1 #include <stdio.h>
2 #include <sys/socket.h>//socket
3 #include <netinet/in.h>//struct sockaddr_in
4 #include <arpa/inet.h>//inet_pton  inet_addr
5 #include <string.h>//bzero
6 #include <stdlib.h>//_exit
7 #include <pthread.h>//线程相关函数
8 #include <unistd.h>
9 typedef struct {
10     int cfd;//存放已连接套接字
11     struct sockaddr_in addr;//存放客户端的信息
12 }CLIENT_MSG;
13 void *deal_client_fun(void *arg)
14 {
15     CLIENT_MSG *p = (CLIENT_MSG *)arg;
16
17     //打印客户端的信息
18     char ip[16]="";
19     unsigned short port = 0;
20     inet_ntop(AF_INET, &p‐>addr.sin_addr.s_addr, ip, 16);
21     port = ntohs(p‐>addr.sin_port);
22     printf("%s %hu connected\n", ip, port);
23
24     //while获取客户端的请求 并回应
25     while(1)
26     {
27         unsigned char buf[1500]="";
28         int len = recv(p‐>cfd, buf, sizeof(buf), 0);
29         if(len <= 0)
30         {
31             printf("%s %hu 退出了\n", ip, port);
32             close(p‐>cfd);
33             break;
34         }
35         else
36         {
37             printf("%s %d:%s\n", ip, port, buf);
38             send(p‐>cfd, buf, len, 0);
39         }
40     }
41
42     //释放堆区空间
43     if(p != NULL)
44     {
45         free(p);
46         p=NULL;
47     }
48     
49     //线程结束
50     pthread_exit(NULL);
51
52     return NULL;
53 }
54 int main(int argc, char const *argv[])
55 {
56     if(argc != 2)
57     {
58         printf("./a.out 8000\n");
59         _exit(‐1);
60     }
61
62     //1、创建tcp监听套接字
63     int lfd = socket(AF_INET, SOCK_STREAM, 0);
64     if(lfd < 0)
65     {
66         perror("socket");
67         _exit(‐1);
68     }
69
70     //设置端口复用
71     int opt = 1;
72     setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));    
73
74     //2、bind给服务器的监听套接字 绑定固定的IP、port
75     struct sockaddr_in my_addr;
76     bzero(&my_addr, sizeof(my_addr));
77     my_addr.sin_family = AF_INET;
78     my_addr.sin_port = htons(atoi(argv[1]));
79     my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
80     int ret = bind(lfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
81     if(ret < 0)
82     {
83         perror("bind");
84         _exit(‐1);
85     }
86
87     //3、listen将服务器的套接字主动变被动  创建连接队列 进行监听
88     ret = listen(lfd, 128);
89     if(ret < 0)
90     {
91         perror("listen");
92         _exit(‐1);
93     }
94
95     //4、while‐‐>accept提取客户端
96     while(1)
97     {
98         struct sockaddr_in cli_addr;
99         socklen_t cli_len = sizeof(cli_addr);
100         int cfd = accept(lfd, (struct sockaddr *)&cli_addr, &cli_len);
101
102         CLIENT_MSG *p = (CLIENT_MSG *)calloc(1,sizeof(CLIENT_MSG));
103         p‐>cfd = cfd;
104         p‐>addr = cli_addr;
105
106         //5、一个客户端 创建一个线程
107         pthread_t tid;
108         pthread_create(&tid, NULL, deal_client_fun,  (void *)p);
109         //线程分离
110         pthread_detach(tid);
111     }
112
113     //关闭监听套接字
114     close(lfd);
115     return 0;
116 }

其中
70     //设置端口复用
71     int opt = 1;
72     setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));    
为什么要设置端口复用,设置了有什么作用,详细讲解

在这段代码中,通过设置端口复用,实际上是在告诉操作系统允许重新使用被占用的端口。在网络编程中,端口复用是一个常见的技术手段,其作用和优势如下:

1. 允许快速重启服务器:当服务器进程异常退出或者被关闭后,如果不设置端口复用,操作系统会在一段时间内保持该端口处于TIME_WAIT状态,这样会导致在该端口上无法立即启动新的服务器进程。设置了端口复用后,新的服务器进程可以立即重用之前被占用的端口,快速恢复服务。

2. 提高服务器的健壮性和可用性:在高并发环境下,服务器可能会频繁启动和关闭,如果不设置端口复用,会导致端口资源被长时间占用,从而影响服务器的健壮性和可用性。通过设置端口复用,可以避免端口资源被长时间占用,提高服务器的稳定性。

3. 解决TIME_WAIT状态资源耗尽问题:如果不设置端口复用,在高并发情况下,大量的TIME_WAIT状态连接会消耗系统资源,甚至导致资源耗尽。设置端口复用可以有效减少TIME_WAIT状态连接的数量,避免资源耗尽问题的发生。

总之,设置端口复用可以提高服务器的稳定性、健壮性和可用性,是网络编程中常用的一项技术手段。

端口复用是什么意思,可以详细讲解吗

当一个套接字(Socket)在关闭之后,操作系统会保持一段时间的状态,称为TIME_WAIT状态。在这段时间内,该套接字的端口会被标记为不可用,以防止新的连接使用相同的端口。这个状态持续的时间通常是几分钟,具体取决于操作系统的设置。

端口复用就是一种机制,允许一个端口在短时间内被多个套接字共享或者重新使用。通常情况下,一个套接字关闭后,操作系统会将其端口保留一段时间以处理可能存在的延迟数据包或者断开连接后的数据包。但在某些情况下,如果需要快速重新启动服务器或者处理大量的连接请求,这种行为就会成为一个问题,因为端口会被占用一段时间,导致无法立即重新使用。

通过设置端口复用选项,可以告诉操作系统允许其他套接字在当前套接字关闭后立即绑定到同一端口上,而不必等待TIME_WAIT状态结束。这样可以有效地提高服务器的可用性和响应速度,特别是在高并发的网络环境中。

在实际编程中,可以通过调用`setsockopt`函数来设置端口复用选项,具体是通过设置`SO_REUSEADDR`选项来实现的。当这个选项被设置为1时,表示允许端口复用,操作系统将允许重新绑定到同一端口上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/8951.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AUTOCRAWLER : A Progressive Understanding Web Agent for WebCrawler Generation

AUTOCRAWLER&#xff1a;用于生成 WebCrawler 的渐进式理解 Web 代理 Fudan University;Alibaba Holding-Aicheng Technology-Enterprise Abstract&#xff1a; 网络自动化是一项重要技术&#xff0c;它通过自动化常见的网络操作来完成复杂的网络任务&#xff0c;提高效率并…

【优选算法】——双指针——15. 三数之和

目录 1.题目 2.解法&#xff08;排序双指针&#xff09;&#xff1a; 算法思路&#xff1a; 3.代码实现 1.题目 15. 三数之和 提示 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足…

Clickhouse判断是否在范围中

isIPAddressInRange a表 name range id ------- 美国 ‘172.10.1.1/24’ 1 b表 ip name 172.10.11.2 test 现在去判断b表中的test是在哪个范围 isIPAddressInRange(a.ip, b.range) 判断是否为IPv4还是IPv6 isIPv4String isIPv6String 转换IP toIPv4 toIPv4OrDefault(s…

RT-Thread移植到STM32F407

1、获取RT-Thread源码 首先到rtthread官网下载rt-thread nano后解压 解压后打开后内容如下。 2、系统结构 各文件夹的作用如下&#xff1a; Rt-Thread-nano源码结构 文件夹描述bsp板级支持包components/finshRT-Thread组件docs文档信息include头文件libcpu/arm与arm处理器相…

根文件系统的其他测试

文章目录 一、hello测试程序编写二、程序后台运行1.在后台运行方法2.中文显示测试3.开机自动启动测试 一、hello测试程序编写 &#x1f4a6;我们使用 Linux 的目的就是运行我们自己的软件&#xff0c;我们编译的应用软件一般都使用动态库&#xff0c;使用动态库的话应用软件体…

vue 钩子函数updated什么时候触发

触发时机 updated是Vue生命周期钩子函数之一&#xff0c;在组件的数据变化导致虚拟DOM重新渲染并应用到实际DOM之后触发。具体来说&#xff0c;updated会在以下几种情况下被触发&#xff1a; 初始渲染完成后&#xff1a;当组件首次渲染完成并将虚拟DOM渲染到实际DOM之后&#…

获取两个时间之间的月份

工具类 public static List<String> getMonthBetweenDate(Date startDate, Date endDate) {ArrayList<String> result new ArrayList<String>();SimpleDateFormat sdf new SimpleDateFormat("yyyy.MM");//格式化&#xff0c;调整为自己需要的格…

摩菲Murphy显示器显示表 总线编程器维修PV780B

Murphy仪器维修包括&#xff1a;摩菲数字显示器&#xff1b;摩菲监视仪表&#xff1b;摩菲CAN总线控制器等维修 维修故障包括&#xff1a;黑屏、指示灯无显示&#xff0c;触摸屏上电无反应&#xff0c; 上电蓝屏、白屏&#xff0c;通电几分钟后屏幕变为蓝屏&#xff0c;主板故…

班级综合测评|基于Springboot+vue的班级综合测评管理系统(源码+数据库+文档)

目录 基于Springbootvue的“智慧食堂”系统 一、前言 二、系统设计 三、系统功能设计 1 管理员功能模块 2学生功能模块 3教师功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大…

应用系统集成企业微信的技术方案和最佳实践

本文以springbootvue技术开发的低代码平台为案例&#xff0c;介绍应用系统如何集成企业微信&#xff0c;包括同步企业微信组织用户、单点登录、消息发送等。 在线体验&#xff1a;http://www.yunchengxc.com 1、准备应用 1.1、注册企业微信账号 作为企业微信的企业管理员&a…

铅离子/镉离子绿色荧光探针,具有高特异性高灵敏度

基本信息&#xff1a; 中文名称&#xff1a;铅离子/镉离子绿色荧光探针 英文名称&#xff1a;Leadmium TM Green AM dye 外观&#xff1a;固体或粉末状 规格&#xff1a;10mg、25mg、50mg (可支持定制&#xff09; 纯度&#xff1a;95% 储存条件&#xff1a;-20C避光避湿…

46. UE5 RPG 增加角色受击反馈

在前面的文章中&#xff0c;我们实现了对敌人的属性的初始化&#xff0c;现在敌人也拥有的自己的属性值&#xff0c;技能击中敌人后&#xff0c;也能够实现血量的减少。 现在还需要的就是在技能击中敌人后&#xff0c;需要敌人进行一些击中反馈&#xff0c;比如敌人被技能击中后…

JVM中类加载过程中如何验证文件格式

在JVM中&#xff0c;类加载过程中的验证阶段主要是为了确保加载的Class文件是符合虚拟机规定的Class文件格式&#xff0c;并且没有安全方面的问题。验证阶段主要包括四个部分&#xff1a;文件格式验证、元数据验证、字节码验证和符号引用验证。 关于文件格式验证&#xff0c;这…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-10.1-NXP SDK 移植

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

夸克网盘拉新怎么做?分享网盘拉新攻略!

夸克网盘拉新怎么做&#xff1f;如何通过推广夸克网盘来赚佣金&#xff1f;相信大家应该都使用过夸克网盘&#xff0c;现在夸克网盘的拉新赚佣金活动开展的如火如荼&#xff0c;不少朋友通过夸克网盘拉新赚取收益&#xff0c;真的很香。还有一部分想要赚佣金但是不知道如何操作…

C语言例题39、输入一个正整数,将其反方向逆序输出

#include <stdio.h>void main() {int x;int ge; //个位int result 0;printf("请输入一个正整数&#xff1a;");scanf("%d", &x);while (x > 0) {//解题原理ge x % 10;//每次分解取得个位的数字result result * 10 ge;//个十百千万顺序向左…

给数据库贴标签

要给数据库中的文本贴标签&#xff0c;你需要创建一个新的表格来存储标签&#xff0c;并且与文本表进行关联。以下是一个示例的口语化的创建表格和查询示例&#xff1a; 创建标签表格&#xff1a; CREATE TABLE IF NOT EXISTS labels (标签ID INTEGER PRIMARY KEY,标签名称 T…

libcity 笔记:添加自定义dataset

假设我们把libcity/data/dataset/trajectory_dataset.py复制一份到libcity/data/dataset/dataset_subclass/GeolifeDM_dataset.py&#xff0c;里面内容不变&#xff0c;只是把class的名字换了 那其他需要修改哪些内容&#xff0c;使得这个dataset生效呢 libcity/data/dataset/d…

Python应用:让生活更智能

随着科技的进步&#xff0c;Python已成为一种非常受欢迎的编程语言&#xff0c;它在数据分析、人工智能、Web开发等领域有着广泛的应用。今天&#xff0c;我们将探讨一个Python应用的例子&#xff0c;这个应用将帮助我们更智能地管理日常生活。 应用名称&#xff1a;智能生活助…

福建 | 福建铭发用行动诠释“敢为天下先”的泉州精神

福建铭发 泉州TOP级企业 在福建&#xff0c;提到混凝土搅拌站&#xff0c;铭发是绕不开的一个存在。 他们是当地最早一批建成的商砼企业&#xff0c;也是如今发展规模最大的TOP级企业。 从2007年建站至今&#xff0c;近15年的发展&#xff0c;他们形成了一套铭发特色的企业经…