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

C++在Linux实现多线程和多进程的TCP服务器和客户端通信

多进程版本

服务器

#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>
#include <string>
void mywait(int num)
{while(1){pid_t pid=waitpid(-1,NULL,WNOHANG);//非阻塞回收进程if(pid>0)printf("回收了%d\n",pid);if(pid==0||pid==-1)break;}
}
int main()
{int flag=0;struct sockaddr_in saddr;saddr.sin_port = htons(8999);saddr.sin_addr.s_addr = INADDR_ANY;saddr.sin_family = AF_INET;int sfd = socket(AF_INET, SOCK_STREAM, 0);struct sigaction sig;sigemptyset(&sig.sa_mask);sig.sa_flags=0;sig.sa_handler=mywait;sigaction(SIGCHLD,&sig,NULL);//设置SIGCHLD信号捕捉if (sfd == -1){perror("socket error");return 1;}flag = bind(sfd, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in));if (flag == -1){perror("bind error");return 1;}flag=listen(sfd, 100);if(flag==-1){perror("listen error");return 1;}struct sockaddr_in caddr;int clen=sizeof(caddr);while (1){int cfd = accept(sfd, (struct sockaddr*)&caddr, (socklen_t*)&clen);if (cfd == -1){perror("accept error");continue;}char ip[1024]={'\0'};//必须加上,不然解析IP会失败printf("接收到了客户端%s:%d的连接\n",inet_ntop(AF_INET,&caddr.sin_addr,ip,1024),ntohs(caddr.sin_port));int pid=fork();if(pid==0){close(sfd);while(1){char buf[1024] = {'\0'};flag = recv(cfd, buf, 1024, 0);if (flag==-1){perror("read error");break;}else if(flag==0){printf("连接断开\n");break;}printf("从客户端收到数据:%s\n", buf);std::string sendstr="服务器收到了"+std::to_string(caddr.sin_port)+"的数据";flag = send(cfd, sendstr.c_str(), sendstr.length(), 0);if (flag == -1){perror("send error");break;}memset(buf, 0, 1024);}exit(0);}else{close(cfd);}}return 0;
}

客户端

#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string>
int main()
{int flag;struct sockaddr_in* caddr=(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));inet_pton(AF_INET, "192.168.101.231", &caddr->sin_addr.s_addr);caddr->sin_family = AF_INET;caddr->sin_port = htons(8999);int cfd = socket(AF_INET, SOCK_STREAM, 0);if (cfd == -1){perror("socket error");return 1;}flag= connect(cfd, (struct sockaddr*)caddr, sizeof(struct sockaddr));//caddr就是指针类型if (flag == -1){perror("connect error");return 1;}int i=0;while (1){char buf[1024] = {'\0'};std::string sendstr="我是客户端,我发送了"+std::to_string(i);flag = send(cfd,  sendstr.c_str(), sendstr.length(),0);if (flag == -1){perror("send error");continue;}printf("send:%s\n", sendstr.c_str());flag = recv(cfd, buf, 1024, 0);if (flag == -1){perror("recv error");continue;}printf("客户端收到数据:%s\n", buf);memset(buf, 0, 1024);i++;sleep(1);}close(cfd);return 0;
}

多线程版本服务器

#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string>
#include <pthread.h>
void* handle(void* arg)
{int flag=0;int* arr=(int*)arg;int cfd=arr[0];int port=arr[1];while(1){char buf[1024] = {'\0'};flag = recv(cfd, buf, 1024, 0);if (flag==-1){perror("read error");break;}else if(flag==0){printf("连接断开\n");break;}printf("从客户端%d收到数据:%s\n",port,buf);std::string sendstr="服务器收到了"+std::to_string(port)+"的数据";flag = send(cfd, sendstr.c_str(), sendstr.length(), 0);if (flag == -1){perror("send error");break;}memset(buf, 0, 1024);}close(cfd);return NULL;
}
int main()
{int flag=0;struct sockaddr_in saddr;saddr.sin_port = htons(8999);saddr.sin_addr.s_addr = INADDR_ANY;saddr.sin_family = AF_INET;int sfd = socket(AF_INET, SOCK_STREAM, 0);if (sfd == -1){perror("socket error");return 1;}flag = bind(sfd, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in));if (flag == -1){perror("bind error");return 1;}flag=listen(sfd, 100);if(flag==-1){perror("listen error");return 1;}while (1){struct sockaddr_in caddr;int clen=sizeof(caddr);int cfd = accept(sfd, (struct sockaddr*)&caddr, (socklen_t*)&clen);int port=ntohs(caddr.sin_port);printf("端口号:%d\n",port);if (cfd == -1){perror("accept error");continue;}char ip[1024]={'\0'};//必须加上,不然解析IP会失败printf("接收到了客户端%s:%d的连接\n",inet_ntop(AF_INET,&caddr.sin_addr,ip,1024),port);pthread_t tid;int arg[2]={cfd,port};pthread_create(&tid,NULL,handle,(void*)arg);//这里不能传递cfd的地址,各个线程是共享这个地址的pthread_detach(tid);}return 0;
}

 运行效果:

相关文章:

C++在Linux实现多线程和多进程的TCP服务器和客户端通信

多进程版本 服务器 #include <arpa/inet.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/wait.h> #include <signal.h> #include <string&…...

音视频开发常见的开源项目汇总

FFmpeg 地址&#xff1a;https://ffmpeg.org/介绍&#xff1a;FFmpeg 是一个非常强大的开源多媒体框架&#xff0c;它可以用来处理视频和音频文件。它支持多种格式的转换、编码、解码、转码、流处理等。FFmpeg 包括了 libavformat、libavcodec、libavutil、libswscale、libpos…...

Java操控Redis (面经之 使用Redis)

操控Redis的工具 ReactiveRedisTemplate 和 RedisTemplate : RedisTemplate&#xff1a; 它是一个通用的模板类&#xff0c;可以使用任何序列化策略来序列化和反序列化键和值。默认情况下&#xff0c;它使用 JdkSerializationRedisSerializer 序列化值&#xff0c;并使用 Strin…...

【计网】从零开始使用UDP进行socket编程 --- 服务端业务实现

在我们每个人都曾经历过“沮丧”时刻里&#xff0c; 如果我们不能对别人说有益的好话&#xff0c; 那我们最好还是什么也别说。 --- 卡耐基 《人性的弱点》--- 从零开始使用UDP进行socket编程 1 前情提要2 单词翻译2.1 业务需求2.2 设计字典类2.3 服务端与客户端逻辑2.4 运…...

正式发售!《黑神话:悟空》背后的技术力量——UE5与实时云渲染

千呼万唤始出来&#xff0c;《黑神话&#xff1a;悟空》终于在今年8月发售了&#xff0c;相信大家都已经玩起来了&#xff01; 作为国产游戏的画质巅峰之作&#xff0c;《黑神话&#xff1a;悟空》凭借其令人叹为观止的画面质量和游戏体验&#xff0c;赢得了广泛的好评。这一切…...

qt-creator-10.0.2之后版本的jom.exe编译速度慢下来了

1、Qt的IDE一直在升级&#xff0c;qt-creator的新版本下载地址 https://download.qt.io/official_releases/qtcreator/ 2、本人一直用的是qt-creator-10.0.2版本&#xff0c;官网历史仓库可以下载安装包qt-creator-opensource-windows-x86_64-10.0.2.exe https://download.qt…...

2024CSP-J初赛全真模拟卷选择题篇(原创,难度偏简单)

注意&#xff0c;本卷由再临TSC原创&#xff0c;禁止转载&#xff01; 本卷难度偏简单&#xff0c;若想要通过初赛本卷应拿80分左右 查看答案的方法&#xff1a; if(设备"PC") { 把光标移到答案上面&#xff0c;选中答案&#xff0c;就会显示()&#xff1b; } …...

【Android 13源码分析】WindowContainer窗口层级-4-Layer树

在安卓源码的设计中&#xff0c;将将屏幕分为了37层&#xff0c;不同的窗口将在不同的层级中显示。 对这一块的概念以及相关源码做了详细分析&#xff0c;整理出以下几篇。 【Android 13源码分析】WindowContainer窗口层级-1-初识窗口层级树 【Android 13源码分析】WindowCon…...

C# 开发教程-中级教程

1.C# 多线程/异步 C# 异步编程Task整理&#xff08;一&#xff09; C# 异步编程Task整理&#xff08;二&#xff09;异常捕捉 C# 异步编程Task(三) async、await C#中创建线程&#xff0c;创建带参数的线程 C# 线程同步之排它锁/Monitor监视器类 C# lock关键词/lock语句块…...

【C++】c++的继承

目录 思维导图大纲&#xff1a; 1.基类和派生类 1.1 定义格式 1.2 继承方式 1.3 基类和派生类的转换 2. 继承中的作用域(隐藏关系) 2.1 考察继承作⽤域相关选择题 3. 派生类的默认成员函数 4. 继承类模板 5. 一个不能被继承的类 ​编辑 6.继承与友元 ​编辑 7. 继…...

【ShuQiHere】 进制转换的世界:从十进制到二进制、十六进制的转换技巧

【ShuQiHere】 在计算机科学中&#xff0c;进制转换&#xff08;Radix Conversion&#xff09; 是一个基础且非常重要的技能。无论是理解计算机的存储、数据表示&#xff0c;还是在编程中处理不同的进制数据&#xff0c;进制转换都是不可或缺的。本文将详细讲解 十进制&#x…...

《化工管理》

《化工管理》征稿简则 《化工管理》杂志是由中国石油和化学工业联合会主管、中国化工企业管理协会主办&#xff0c;1986年创刊&#xff0c;在国内外公开发行&#xff0c;国内统一连续出版物号&#xff1a;CN 11—3991/F&#xff0c;中国标准连续出版物号&#xff1a;ISSN 1008—…...

LeetCode70:爬楼梯

class Solution { public:int climbStairs(int n) {if(n 1) return 1;if(n 2) return 2;vector<int> dp(n 1, 0);dp[1] 1;dp[2] 2;for(int i 3; i < n 1; i){dp[i] dp[i - 1] dp[i - 2];}return dp[n];} }; 这个题目也就是最简单的动态规划&#xff0c;题目…...

[程序员] 前人留下的苦难源,我们是否有勇气改正?

最近遇到一个客户现场发现的&#xff0c;表象是网络有问题&#xff0c;分析一圈下来发现是程序进入了某种死循环状态&#xff0c;耗尽CPU。 产品里的很多线程/进程的优先级设置的很高&#xff0c;甚至高过了内核运行程序的优先级&#xff0c;高过了产品内警告处理程序的运行&a…...

聚类_K均值

import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import make_blobs1.数据预处理 #创建基于高斯分布的样本点, x是点的坐标&#xff0c;y是所属聚类值 x, y make_blobs(n_samples100, centers6, random_state100, cluster_std0.6) # 设置图形尺寸…...

Mac电脑剪切板在哪里找 苹果电脑剪切板打开教程【详解】

Windows 和 Mac 电脑在使用方式上存在一些差异&#xff0c;许多习惯了 Windows 系统的用户初次接触 Mac 时可能会对某些操作感到困惑。比如&#xff0c;很多人会问&#xff1a;Mac 上的剪贴板在哪里&#xff1f;如果你也有这样的疑问&#xff0c;不妨看看下面这篇关于如何在 Ma…...

Python编程 - 三器一包

目录 前言 一、迭代器 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;迭代器和可迭代对象 &#xff08;三&#xff09;创建迭代器 &#xff08;四&#xff09;内置迭代器函数 &#xff08;五&#xff09;优点和局限性 二、生成器 &#xff08;一&…...

InternVL 多模态模型部署微调实践

友情链接 该文档参考InternVL垂直领域场景微调实践而写成&#xff0c;感谢社区同学法律人的文档。 写在前面&#xff08;什么是InternVL&#xff09; InternVL 是一种用于多模态任务的深度学习模型&#xff0c;旨在处理和理解多种类型的数据输入&#xff0c;如图像和文本。它…...

Ruby Dir 类和方法

Ruby Dir 类和方法 Ruby 中的 Dir 类提供了用于处理目录的各种方法。这些方法允许您列出目录内容、更改当前工作目录、创建和删除目录等。本文将详细介绍 Dir 类的常用方法&#xff0c;并通过示例展示如何使用它们。 目录 Dir 类的简介常用方法 Dir.chdirDir.childrenDir.de…...

C++STL~~deque

文章目录 deque的概念deque的使用deque的练习总结 deque的概念 deque(双端队列)&#xff1a;是一种序列容器、是一种双开口的"连续"空间的数据结构&#xff0c;双开口的含义是&#xff1a;可以在头尾两端进行插入和删除操作&#xff0c;且时间复杂度为O(1)&#xff…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...