多进程/线程并发服务器

多进程:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>#define SER_PORT 8888
#define SER_IP  "192.168.124.242"   //"0.0.0.0"int deal_cli_msg( int newfd, struct sockaddr_in cin);int main(int argc, const char *argv[])
{//创建流式套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("socket");return -1;}printf("socket success __%d__\n", __LINE__);//允许端口快速重用                                                                                  int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("setsockopt");return -1;}printf("reuseaddr success __%d__\n", __LINE__);//若从命令行传入端口号,则使用传入的端口号,没有传入则使用宏定义的端口号int port =  argc>=2?atoi(argv[1]):SER_PORT;//填充服务器的地址信息结构体,给bind函数使用//真实的地址信息结构体根据地址族指定 AF_INET: man 7 ipstruct sockaddr_in sin;sin.sin_family      = AF_INET;              //必须填AF_INETsin.sin_port        = htons(port);          //端口号的网络字节序,1024~49151sin.sin_addr.s_addr = inet_addr(SER_IP);    //本机IP的网络字节序,ifconfig查看本机IP//127.0.0.1:本地换回IP,只能做本机通信的IP//0.0.0.0 : 代表运行环境中所有可用IP//绑定服务器自身的地址信息if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("bind");return -1;}printf("bind success __%d__\n", __LINE__);//将套接字设置为被动监听状态if(listen(sfd, 128) < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("listen");return -1;}printf("listen success __%d__\n", __LINE__);//阻塞等待客户端连接成功,从已完成连接的队列头中获取一个客户端信息,//生成一个新的文件描述符,这个新的文件描述符才是与客户端通信用的文件描述符struct sockaddr_in cin;     //存储获取到的客户端的地址信息socklen_t addrlen = sizeof(cin);int newfd = -1;pid_t pid = 0;while(1){//父进程负责处理客户端连接事件newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);if(newfd < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("accpet");return -1;}printf("client connect success, [%s:%d] newfd = %d __%d__\n", \inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, __LINE__);//有客户端连接成功,需要创建子进程负责与客户端通信pid = fork();if( 0 == pid){close(sfd);//子进程中的sfddeal_cli_msg(newfd, cin);break;        //or exit(0);子进程只负责与客户端交互,客户端退出,子进程需要结束}close(newfd);//父进程的newfd;}close(sfd);//父进程中的sfdreturn 0;
}int deal_cli_msg( int newfd, struct sockaddr_in cin)
{char buf[128] = "";ssize_t res = 0;while(1){bzero(buf, sizeof(buf));    //memset(buf, 0, sizeof(buf));//收res = recv(newfd, buf, sizeof(buf), 0);if(res < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("recv");return -1;}else if(0 == res){printf("client [%s:%d] offline  __%d__\n",\inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), __LINE__);break;}printf("[%s:%d] newfd=%d : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, buf);//发strcat(buf, "*_*");if(send(newfd, buf, sizeof(buf), 0) < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("send");return -1;}printf("send success __%d__\n", __LINE__);}close(newfd);//子进程中的newfdreturn 0;
}

多线程:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>#define SER_PORT 8888
#define SER_IP  "192.168.124.242"   //"0.0.0.0"int deal_cli_msg( int newfd, struct sockaddr_in cin);int main(int argc, const char *argv[])
{//创建流式套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("socket");return -1;}printf("socket success __%d__\n", __LINE__);//允许端口快速重用                                                                                  int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("setsockopt");return -1;}printf("reuseaddr success __%d__\n", __LINE__);//若从命令行传入端口号,则使用传入的端口号,没有传入则使用宏定义的端口号int port =  argc>=2?atoi(argv[1]):SER_PORT;//填充服务器的地址信息结构体,给bind函数使用//真实的地址信息结构体根据地址族指定 AF_INET: man 7 ipstruct sockaddr_in sin;sin.sin_family      = AF_INET;              //必须填AF_INETsin.sin_port        = htons(port);          //端口号的网络字节序,1024~49151sin.sin_addr.s_addr = inet_addr(SER_IP);    //本机IP的网络字节序,ifconfig查看本机IP//127.0.0.1:本地换回IP,只能做本机通信的IP//0.0.0.0 : 代表运行环境中所有可用IP//绑定服务器自身的地址信息if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("bind");return -1;}printf("bind success __%d__\n", __LINE__);//将套接字设置为被动监听状态if(listen(sfd, 128) < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("listen");return -1;}printf("listen success __%d__\n", __LINE__);//阻塞等待客户端连接成功,从已完成连接的队列头中获取一个客户端信息,//生成一个新的文件描述符,这个新的文件描述符才是与客户端通信用的文件描述符struct sockaddr_in cin;     //存储获取到的客户端的地址信息socklen_t addrlen = sizeof(cin);int newfd;pthread_t tid;struct Climsg pcli;while(1){//主线程负责处理客户端连接事件newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);if(newfd < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("accpet");return -1;}printf("client connect success, [%s:%d] newfd = %d __%d__\n", \inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, __LINE__);//有客户端连接成功,需要创建一个子线程负责与客户端通信pthread_create( &tid, NULL, deal_cli_msg, (void*)&pcli);pthread_detach( tid);}close(sfd);//父进程中的sfdreturn 0;
}//线程回调函数
void* deal_cli_msg( void* arg )
{int newfd = ( (struct Climsg*)arg )->newfd;struct sockaddr_in cin = ( (struct Climsg*)arg)->cin;char buf[128] = "";ssize_t res = 0;while(1){bzero(buf, sizeof(buf));    //memset(buf, 0, sizeof(buf));//收res = recv(newfd, buf, sizeof(buf), 0);if(res < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("recv");return -1;}else if(0 == res){printf("client [%s:%d] offline  __%d__\n",\inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), __LINE__);break;}printf("[%s:%d] newfd=%d : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, buf);//发strcat(buf, "*_*");if(send(newfd, buf, sizeof(buf), 0) < 0){fprintf(stderr, "__%d__ ", __LINE__);perror("send");return -1;}printf("send success __%d__\n", __LINE__);}close(newfd);//子线程中的newfdpthread_exit( NULL);
}

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

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

相关文章

Oracle ADB 导入 BANK_GRAPH 的学习数据

Oracle ADB 导入 BANK_GRAPH 的学习数据 1. 下载数据2. 导入数据运行 setconstraints.sql 1. 下载数据 访问 https://github.com/oracle-quickstart/oci-arch-graph/tree/main/terraform/scripts&#xff0c;下载&#xff0c; bank_accounts.csvbank_txns.csvsetconstraints.…

985研一学习日记 - 2024.11.14

一个人内耗&#xff0c;说明他活在过去&#xff1b;一个人焦虑&#xff0c;说明他活在未来。只有当一个人平静时&#xff0c;他才活在现在。 日常 1、起床6:00 2、健身2h 3、LeetCode刷了题 动态规划概念 如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的…

1.两数之和-力扣(LeetCode)

题目&#xff1a; 解题思路&#xff1a; 在解决这个问题之前&#xff0c;首先要明确两个点&#xff1a; 1、参数returnSize的含义是返回答案的大小&#xff08;数目&#xff09;&#xff0c;由于这里的需求是寻找数组中符合条件的两个数&#xff0c;那么当找到这两个数时&#…

【excel】easy excel如何导出动态列

动态也有多重含义&#xff1a;本文将描述两种动态场景下的解决方案 场景一&#xff1a;例如表头第一列固定为动物&#xff0c;且必定有第二列&#xff0c;第二列的表头可能为猫 也可能为狗&#xff1b;这是列数固定&#xff0c;列名不固定的场景&#xff1b; 场景二&#xff1…

〔 MySQL 〕数据类型

目录 1.数据类型分类 2 数值类型 2.1 tinyint类型 2.2 bit类型 2.3 小数类型 2.3.1 float 2.3.2 decimal 3 字符串类型 3.1 char 3.2 varchar 3.3 char和varchar比较 4 日期和时间类型 5 enum和set mysql表中建立属性列&#xff1a; 列名称&#xff0c;类型在后 n…

LlamaIndex

一、大语言模型开发框架 SDK:Software Development Kit,它是一组软件工具和资源的集合,旨在帮助开发者创建、测试、部署和维护应用程序或软件。 所有开发框架(SDK)的核心价值,都是降低开发、维护成本。 大语言模型开发框架的价值,是让开发者可以更方便地开发基于大语言…

【FFmpeg】FFmpeg 函数简介 ③ ( 编解码相关函数 | FFmpeg 源码地址 | FFmpeg 解码器相关 结构体 和 函数 )

文章目录 一、FFmpeg 解码器简介1、解码流程分析2、FFmpeg 编解码器 本质3、FFmpeg 编解码器 ID 和 名称 二、FFmpeg 解码器相关 结构体 / 函数1、AVFormatContext 结构体2、avcodec_find_decoder 函数 - 根据 ID 查找 解码器3、avcodec_find_decoder_by_name 函数 - 根据 名称…

Linux——GPIO输入输出裸机实验

学习了正点原子Linux环境下的GPIO的输入输出的裸机实验学习&#xff0c;现在进行一下小结&#xff1a; 启动文件start.S的编写 .global _start .global _bss_start _bss_start:.word __bss_start.global _bss_end _bss_end:.word __bss_end_start:/*设置处理器进入SVC模式*/m…

zabbix搭建钉钉告警流程

目录 &#x1f324;️zabbix实验规划 &#x1f324;️zabbix实验步骤 &#x1f4d1;1 使用钉钉添加一个自定义的机器人 ​ &#x1f4d1;2在zabbix-server上编写钉钉信息发送脚本&#xff0c;设置钉钉报警媒介 ☁️ 设置钉钉报警媒介​编辑​编辑 ☁️在添加消息模板​编辑​…

Java 多线程(三)—— 死锁

死锁的产生 我们先从简单的死锁最后到难一些的死锁问题开始展开讨论。 首先一个线程&#xff0c;一把锁&#xff0c;因为多次加锁而导致死锁问题&#xff0c;由于Java 的synchronized 实现了可重入锁&#xff0c;因此这个死锁问题就不存在了&#xff0c;意味着当一个线程拥有…

makefile 设置动态库路径参数

目录 一、makefile 动态库相关1.1 Libs 变量1.2 LDFLAGS 变量1.3 二者的作用和区别 二、设置方式2.1 编译时指定库路径2.2 运行时指定库路径 三、测试 一、makefile 动态库相关 1.1 Libs 变量 在 Makefile 中&#xff0c;Libs 通常是一个变量&#xff0c;用于存储链接器&…

Servlet入门 Servlet生命周期 Servlet体系结构

一.Servlet入门 1.Servlet介绍 Servlet (server applet) 是运行在服务端(tomcat)的Java小程序&#xff0c;是sun公司提供一套定义动态资源规范; 从代码层面上来讲Servlet就是一个接口 狭义的Servlet是指Java语言编写的一个接口。 广义的Servlet是指任何实现了这个Servlet接口…

穿越数据迷宫:C++哈希表的奇幻旅程

文章目录 前言&#x1f4d4;一、unordered系列关联式容器&#x1f4d5;1.1 unordered 容器概述&#x1f4d5;1.2 哈希表在 unordered 容器中的实现原理&#x1f4d5;1.3 unordered 容器的特点 &#x1f4d4;二、unordered_set 和 unordered_map 的基本操作&#x1f4d5;2.1 un…

飞牛云fnOS本地部署WordPress个人网站并一键发布公网远程访问

文章目录 前言1. Docker下载源设置2. Docker下载WordPress3. Docker部署Mysql数据库4. WordPress 参数设置5. 飞牛云安装Cpolar工具6. 固定Cpolar公网地址7. 修改WordPress配置文件8. 公网域名访问WordPress 前言 本文旨在详细介绍如何在飞牛云NAS上利用Docker部署WordPress&a…

2023年MathorCup数学建模B题城市轨道交通列车时刻表优化问题解题全过程文档加程序

2023年第十三届MathorCup高校数学建模挑战赛 B题 城市轨道交通列车时刻表优化问题 原题再现&#xff1a; 列车时刻表优化问题是轨道交通领域行车组织方式的经典问题之一。列车时刻表规定了列车在每个车站的到达和出发&#xff08;或通过&#xff09;时刻&#xff0c;其在实际…

安全见闻1-5

涵盖了编程语言、软件程序类型、操作系统、网络通讯、硬件设备、web前后端、脚本语言、病毒种类、服务器程序、人工智能等基本知识&#xff0c;有助于全面了解计算机科学和网络技术的各个方面。 安全见闻1 1.编程语言简要概述 C语言&#xff1a;面向过程&#xff0c;适用于系统…

闯关leetcode——3178. Find the Child Who Has the Ball After K Seconds

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/find-the-child-who-has-the-ball-after-k-seconds/description/ 内容 You are given two positive integers n and k. There are n children numbered from 0 to n - 1 standing in a queue in o…

Java结合ElasticSearch根据查询关键字,高亮显示全文数据。

由于es高亮显示机制的问题。当全文内容过多&#xff0c;且搜索中标又少时&#xff0c;就会出现高亮结果无法覆盖全文。因此需要根据需求手动替换。 1.根据es的ik分词器获取搜索词的分词结果。 es部分&#xff1a; //中文分词解析 post /_analyze {"analyzer":"…

Python——NumPy库的简单用法,超级详细教程使用

一、什么是NumPy库 NumPy&#xff1a;它是python的一个科学计算库函数&#xff0c;它是由c语言编写的 它应用于数据处理、机器学习、图像处理、文件操作等等 二、array函数 这里导入库numpy&#xff0c;命名为np&#xff0c;后面的np都是代表着是numpy函数 array函数表示创建…

【Java语言】String类

在C语言中字符串用字符可以表示&#xff0c;可在Java中有单独的类来表示字符串&#xff08;就是String&#xff09;&#xff0c;现在我来介绍介绍String类。 字符串构造 一般字符串都是直接赋值构造的&#xff0c;像这样&#xff1a; 还可以这样构造&#xff1a; 图更能直观的…