当前位置: 首页 > news >正文

l8-d8 TCP并发实现

一、TCP多进程并发

1.地址快速重用

先退出服务端,后退出客户端,则服务端会出现以下错误:

地址仍在使用中

解决方法:

/*地址快速重用*/
    int flag=1,len= sizeof (int);
    if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len) == -1) {
              perror("setsockopt");
              exit(1);
    }

 2.多进程并发

1)fork函数

#include <stdio.h>
#include <wait.h>
#include <stdlib.h>int main(int argc, char *argv[])
{pid_t pid = fork();if(pid < 0){perror("fork");exit(0);}else if(pid == 0){printf("This is child process.\n");}else{printf("This is father process.\n");wait(NULL);}return 0;
}

2)多个客户端

代码演示

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>#define BACKLOG 5
void ClinetHandle(int newfd);
int main(int argc, char *argv[])
{int fd, newfd;struct sockaddr_in addr, clint_addr;socklen_t addrlen = sizeof(clint_addr);pid_t pid;if(argc < 3){fprintf(stderr, "%s<addr><port>\n", argv[0]);exit(0);}/*创建套接字*/fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if ( inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*地址快速重用*/int flag=1,len= sizeof (int); if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len) == -1) { perror("setsockopt"); exit(1); } /*绑定通信结构体*/if(bind(fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1){perror("bind");exit(0);}/*设置套接字为监听模式*/if(listen(fd, BACKLOG) == -1){perror("listen");exit(0);}while(1){/*接受客户端的连接请求,生成新的用于和客户端通信的套接字*/newfd = accept(fd, (struct sockaddr *)&clint_addr, &addrlen);if(newfd < 0){perror("accept");exit(0);}printf("addr:%s port:%d\n", inet_ntoa(clint_addr.sin_addr), ntohs(clint_addr.sin_port) );if( (pid = fork() ) < 0){perror("fork");exit(0);}else if(pid == 0){close(fd);ClinetHandle(newfd);exit(0);}elseclose(newfd);}close(fd);return 0;
}
void ClinetHandle(int newfd){int ret;char buf[BUFSIZ] = {};while(1){//memset(buf, 0, BUFSIZ);bzero(buf, BUFSIZ);        //初始化ret = read(newfd, buf, BUFSIZ);if(ret < 0){perror("read");exit(0);}else if(ret == 0)break;elseprintf("buf = %s\n", buf);}close(newfd);
}

二、僵尸进程处理

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <sys/wait.h>#define BACKLOG 5
void SigHandle(int sig){if(sig == SIGCHLD){printf("client exited\n");wait(NULL);}
}
void ClinetHandle(int newfd);
int main(int argc, char *argv[])
{int fd, newfd;struct sockaddr_in addr, clint_addr;socklen_t addrlen = sizeof(clint_addr);#if 0struct sigaction act;act.sa_handler = SigHandle;act.sa_flags = SA_RESTART;sigemptyset(&act.sa_mask);sigaction(SIGCHLD, &act, NULL);
#elsesignal(SIGCHLD, SigHandle);
#endifpid_t pid;if(argc < 3){fprintf(stderr, "%s<addr><port>\n", argv[0]);exit(0);}/*创建套接字*/fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if ( inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*地址快速重用*/int flag=1,len= sizeof (int); if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len) == -1) { perror("setsockopt"); exit(1); } /*绑定通信结构体*/if(bind(fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1){perror("bind");exit(0);}/*设置套接字为监听模式*/if(listen(fd, BACKLOG) == -1){perror("listen");exit(0);}while(1){/*接受客户端的连接请求,生成新的用于和客户端通信的套接字*/newfd = accept(fd, (struct sockaddr *)&clint_addr, &addrlen);if(newfd < 0){perror("accept");exit(0);}printf("addr:%s port:%d\n", inet_ntoa(clint_addr.sin_addr), ntohs(clint_addr.sin_port) );if( (pid = fork() ) < 0){perror("fork");exit(0);}else if(pid == 0){close(fd);ClinetHandle(newfd);exit(0);}elseclose(newfd);}close(fd);return 0;
}
void ClinetHandle(int newfd){int ret;char buf[BUFSIZ] = {};while(1){//memset(buf, 0, BUFSIZ);bzero(buf, BUFSIZ);ret = read(newfd, buf, BUFSIZ);if(ret < 0){perror("read");exit(0);}else if(ret == 0)break;elseprintf("buf = %s\n", buf);}close(newfd);
}

三、TCP并发多线程

 

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <pthread.h>#define BACKLOG 5void *ClinetHandle(void *arg);
int main(int argc, char *argv[])
{int fd, newfd;struct sockaddr_in addr, clint_addr;pthread_t tid;socklen_t addrlen = sizeof(clint_addr);if(argc < 3){fprintf(stderr, "%s<addr><port>\n", argv[0]);exit(0);}/*创建套接字*/fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if ( inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*地址快速重用*/int flag=1,len= sizeof (int); if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len) == -1) { perror("setsockopt"); exit(1); } /*绑定通信结构体*/if(bind(fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1){perror("bind");exit(0);}/*设置套接字为监听模式*/if(listen(fd, BACKLOG) == -1){perror("listen");exit(0);}while(1){/*接受客户端的连接请求,生成新的用于和客户端通信的套接字*/newfd = accept(fd, (struct sockaddr *)&clint_addr, &addrlen);if(newfd < 0){perror("accept");exit(0);}printf("addr:%s port:%d\n", inet_ntoa(clint_addr.sin_addr), ntohs(clint_addr.sin_port) );pthread_create(&tid, NULL, ClinetHandle, &newfd);    //创建线程pthread_detach(tid);    //设置为分离属性}close(fd);return 0;
}
void *ClinetHandle(void *arg){int ret;char buf[BUFSIZ] = {};int newfd = *(int *)arg;    //传参,强转while(1){//memset(buf, 0, BUFSIZ);bzero(buf, BUFSIZ);ret = read(newfd, buf, BUFSIZ);if(ret < 0){perror("read");exit(0);}else if(ret == 0)break;elseprintf("buf = %s\n", buf);}printf("client exited\n");close(newfd);return NULL;
}

Makefile


CC=gcc
CFLAGS=-Wall
all:client server

server:server.c
    $(CC) $^ -Wall -o $@ -lpthread

clean:
    rm client server
 

相关文章:

l8-d8 TCP并发实现

一、TCP多进程并发 1.地址快速重用 先退出服务端&#xff0c;后退出客户端&#xff0c;则服务端会出现以下错误&#xff1a; 地址仍在使用中 解决方法&#xff1a; /*地址快速重用*/ int flag1,len sizeof (int); if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &a…...

编写中间件以用于 Express 应用程序

概述 中间件函数能够访问请求对象 (req)、响应对象 (res) 以及应用程序的请求/响应循环中的下一个中间件函数。下一个中间件函数通常由名为 next 的变量来表示。 中间件函数可以执行以下任务&#xff1a; 执行任何代码。对请求和响应对象进行更改。结束请求/响应循环。调用堆…...

【2023年数学建模国赛】D题解题思路

2023年数学建模国赛D题解题思路 为了解决问题1、问题2和问题3&#xff0c;我们可以采用动态规划方法来制定生产计划&#xff0c;考虑了不确定性因素和多种可能情况的预案集。首先&#xff0c;我们需要定义一些变量和符号&#xff1a; T T T&#xff1a;总的养殖周期&#xff0…...

python爬虫之正则表达式学习

网络安全离不开脚本和工具的开发&#xff0c;python很多又需要正则表达式。 这是一个很好的学习正则表达式的项目 https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md 基本匹配 正则表达式其实就是在执行搜索时的格式&#xff0c;它由一些字…...

智慧能源方案:TSINGSEE青犀AI算法中台在能源行业的应用

一、方案背景 互联网、物联网、人工智能等新一代信息技术引领新一轮产业革命&#xff0c;加快能源革命步伐。尤其是随着人工智能技术的不断发展&#xff0c;AI智能检测与识别技术在能源行业的应用也越来越广泛。与此同时&#xff0c;国家出台多项政策&#xff0c;将智慧能源纳…...

达梦数据库awr报告收集

1、找出快照点snap_id与时间的对应关系 SYS.WRM$_SNAPSHOT表中记录了快照点snap_id与时间的对应关系 例如如下语句可以得出2023-09-04这一天各个时间点对应的快照点snap_id select snap_id,end_interval_time from SYS.WRM$_SNAPSHOT where end_interval_time between to…...

c语言练习43:深入理解strcmp

深入理解strcmp strcmp的主要功能是用来比较两个字符串 模拟实现strcmp 比较两个字符串对应位置上的大小 按字典序进行比较 例如&#xff1a; 输入&#xff1a;abc abc 输出&#xff1a;0 输入&#xff1a;abc ab 输出&#xff1a;>0的数 输入&#xff1a;ab abc …...

NUC980webServer开发

目录 1.RTL8189FTV驱动移植 2.wifi配置工具hostapd移植 1.openssl-1.0.2r交叉编译 2.libnl-3.2.25.tar.gz交叉编译 3.hostapd-2.9.tar.gz交叉编译 4.移植相关工具到开发板 1.RTL8189FTV驱动移植 1. 把驱动文件源码放在linux源码的drivers/net/wireless/realtek/rtlwifi/目录…...

驱动开发--day2

实现三盏灯的控制&#xff0c;编写应用程序测试 head.h #ifndef __HEAD_H__ #define __HEAD_H__#define LED1_MODER 0X50006000 #define LED1_ODR 0X50006014 #define LED1_RCC 0X50000A28#define LED2_MODER 0X50007000 #define LED2_ODR 0X50007014#endif mychrdev.c #inc…...

用户促活留存新方式——在APP中嵌入小游戏

随着APP同类产品的不断出现&#xff0c;APP开发者们面临着激烈的竞争&#xff0c;很多APP下载后被新的APP取代&#xff0c;获客成本越来越高。同时开发者还会面临用户粘性差、忠诚度低、用完即走、留存困难&#xff0c;商业化价值被大大缩减。 在APP中植入小游戏来提高用户活跃…...

MySQL 8.0.34(x64)安装笔记

一、背景 从MySQL 5.6到5.7&#xff0c;再到8.0&#xff0c;版本的跳跃不可谓不大。安装、配置的差别也不可谓不大&#xff0c;特此备忘。 二、过程 &#xff08;1&#xff09;获取MySQL 8.0社区版&#xff08;MySQL Community Server&#xff09;   从 官网 字样 “MySQL …...

物流供应商实现供应链自动化的3种方法

当前影响供应链的全球性问题(如新冠肺炎疫情)正在推动许多物流供应商重新评估和简化其流程。运输协调中的摩擦只会加剧供应商无法控制的现有延误和风险。值得庆幸的是&#xff0c;供应链专业人员可以通过端到端的供应链自动化消除延迟&#xff0c;简化与合作伙伴的沟通&#xf…...

Mysql更新时间列只改日期为指定日期不更改时间

场景 Mysql分表后同结构不同名称表之间复制数据以及Update语句只更新日期加减不更改时间&#xff1a; Mysql分表后同结构不同名称表之间复制数据以及Update语句只更新日期加减不更改时间_霸道流氓气质的博客-CSDN博客 上面通过如下方式实现日期列增加指定天数。 UPDATE bus…...

实时测试工具 Visual Studio 扩展 NCrunch 4.18 Crack

NCrunch Visual Studio 扩展 .NET 的终极实时测试工具 在编码时查看实时测试结果和内联指标。 下载v4.18 发布于 2023 年 7 月 17 日 跳过视频至&#xff1a; 代码覆盖率 指标 分布式处理 配置 发动机模式 Visual Studio 自动并发测试 NCrunch 是一个完全自动化的测试扩展&a…...

Neo4j 基本语法

一、基本语法 1、新建节点 &#xff08;1&#xff09;基本语法&#xff1a; () 代表节点 示例&#xff1a; CREATE (u:User {uid:970939424 }) // 节点类型为User&#xff0c;属性值为uid970939424CREATE (u:Round {rid:7194842697444819113 }) // 节点类型为Rou…...

docker常见面试题

1.什么是docker docker是一个容器化平台&#xff0c;类似于一个集装箱&#xff0c;集装箱与集装箱之间互不影响&#xff0c;docker平台就是一个软件集装箱平台&#xff0c;我们可以构建应用程序&#xff0c;将其所有的依赖打包到一个容器中&#xff0c;然后就很方便的可以在其…...

静态路由:配置和使用详解

文章目录 一、静态路由的配置和使用详解1. 配置要点1.1 点到点接口配置1.2 以太网接口配置 2. 默认路由3. 静态路由的配置命令4. 静态路由实现路由备份和负载分担 二、静态路由的优先级和比较1. 静态路由的优先级设置2. 静态路由与动态路由的比较2.1 静态路由优缺点2.2 动态路由…...

玩转Mysql系列 - 第15篇:详解视图

这是Mysql系列第15篇。 环境&#xff1a;mysql5.7.25&#xff0c;cmd命令中进行演示。 需求背景 电商公司领导说&#xff1a;给我统计一下&#xff1a;当月订单总金额、订单量、男女订单占比等信息&#xff0c;我们啪啦啪啦写了一堆很复杂的sql&#xff0c;然后发给领导。 …...

0065__git fetch, git pull, git merge, git rebase

git fetch, git pull, git merge, git rebase_git pull和merge_送你一朵小莲花的博客-CSDN博客...

AJAX学习笔记4解决乱码问题

AJAX学习笔记3练习_biubiubiu0706的博客-CSDN博客 在Tomcat10来说,AJAX GET或者POST接收响应都不存在乱码问题 对于Tomcat9来说 前端测试代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>测试A…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...