linux并发服务器(一)

UDP服务器 传输层主要应用的协议模型有两种,一种是TCP协议,另外一种则是UDP协议。TCP协议在网络通信中占主导地位,绝大多数的网络通信借助TCP协议完成数据传输。但UDP也是网络通信中不可或缺的重要通信手段。 相较于TCP而言,UDP通信的形式更像是发短信。不需要在数据传输之前建立、维护连接。只专心获取数据就好。省去了三次握手的过程,通信速度可以大大提高,但与之伴随的通信的稳定性和正确率便得不到保证 阅读详情

1.UDP并发服务器(fork方式)

1.1.运行模型

在这里插入图片描述

1.2.示例

#include <stdio.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <time.h>
#include <unistd.h>
#include "errno.h"
#include "signal.h"
#include <stdlib.h>
//#define NULL 0
#define BUFFLEN 1024
#define SERVER_PORT 8888
#define BACKLOG 5
#define PIDNUMB 2

static void handle_connect(int s)
{
    struct sockaddr_in from;
    socklen_t len = sizeof(from);
    int n=0;
    char buff[BUFFLEN];
    time_t now;
    int count = 0;

    printf("handle_connect s=%d buff=%p,count addr=%p,pid=0x%x\n",s,buff,&count,getpid());
    while(1)
    {
        memset(buff,0,BUFFLEN);
        n=recvfrom(s,buff,BUFFLEN,0,(struct sockaddr*)&from,&len);
        if(n>0 &&!strncmp(buff,"TIME",4))
        {
             printf("recv from port=%u data=[%s],pid=0x%x,count=%d\n",ntohs(from.sin_port),buff,getpid(),++count);
             memset(buff,0,BUFFLEN);
             now=time(NULL);
             sprintf(buff,"[%24s]\r\n",ctime(&now));
             sendto(s,buff,strlen(buff),0,(struct sockaddr*)&from,len);
        }
        else
        {
            printf("n=%d,buff=[%s],pid=0x%x\n",n,buff,getpid());
        }
        sleep(5);
    }

}
void sig_int(int num)
{
    exit(1);
}
int main(void)
{
    int ss;
    struct sockaddr_in local;
    signal(SIGINT,sig_int);


    ss=socket(AF_INET,SOCK_DGRAM,0);
    printf("ss=%d\n",ss);

    memset(&local,0,sizeof(local));
    local.sin_family = AF_INET;
    local.sin_addr.s_addr=htonl(INADDR_ANY);
    local.sin_port = htons(SERVER_PORT);



    int res = bind(ss,(struct sockaddr*)&local,sizeof(local));
    printf("bind res=%d\n",res);


    pid_t pid[PIDNUMB];
    int i = 0;
    for(i =0;i<PIDNUMB;i++)
    {
        pid[i]=fork();
        if(pid[i]==0)
        {
            handle_connect(ss);
        }
        else
        {
            printf("pid=%x\n",pid[i]);
        }
    }
    while(1);

    return 0;
}

1.3.客户端发送

在这里插入图片描述
在这里插入图片描述

1.4.运行结果

ss=3
bind res=0
pid=17dbb
pid=17dbc
handle_connect s=3 buff=0x7fff5f3809e0,pid=0x17dbc
handle_connect s=3 buff=0x7fff5f3809e0,pid=0x17dbb
recv from port=56750 data=[TIMEA],pid=0x17dbc
recv from port=56750 data=[TIMEA],pid=0x17dbb
recv from port=56750 data=[TIMEA],pid=0x17dbc
recv from port=56750 data=[TIMEA],pid=0x17dbb
recv from port=56750 data=[TIMEA],pid=0x17dbc
recv from port=56750 data=[TIMEA],pid=0x17dbb
recv from port=56750 data=[TIMEA],pid=0x17dbc
recv from port=56750 data=[TIMEA],pid=0x17dbb
recv from port=56750 data=[TIMEA],pid=0x17dbc
recv from port=56750 data=[TIMEA],pid=0x17dbb
recv from port=56750 data=[TIMEA],pid=0x17dbc
recv from port=56750 data=[TIMEA],pid=0x17dbb
recv from port=62471 data=[TIMEB],pid=0x17dbc
recv from port=62471 data=[TIMEB],pid=0x17dbb
recv from port=62471 data=[TIMEB],pid=0x17dbc
recv from port=62471 data=[TIMEB],pid=0x17dbb
recv from port=62471 data=[TIMEB],pid=0x17dbc
recv from port=62471 data=[TIMEB],pid=0x17dbb
recv from port=62471 data=[TIMEB],pid=0x17dbc
recv from port=62471 data=[TIMEB],pid=0x17dbb

1.5.结果分析

1、两个客户端发送数据,fork出来的进程都能进行处理;
2、对于同一个客户端发送的数据,fork出来的进行能够被调度处理到;
可以想象同一个端口存在一个阻塞队列。备注:在早期的linux版本,存在惊群问题,即会唤醒队列中所有进程,造成性能问题,貌似新版本内核解决方案为只唤醒等待队列上的第一个进程或者线程。
3、fork出来的进程中的同一个函数内变量的地址数值相同,但互补影响(在各自的进程空间中)

2.TCP并发服务器(fork方式)

2.1.运行模型

在这里插入图片描述

2.2.示例

#include <stdio.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <time.h>
#include <unistd.h>
#include "errno.h"
#include "signal.h"
#include <stdlib.h>
//#define NULL 0
#define BUFFLEN 1024
#define SERVER_PORT 8888
#define BACKLOG 5
#define PIDNUMB 2

static void tcp_handle_connect(int ss)
{
    struct sockaddr_in from;
    socklen_t len = sizeof(from);
    int n=0;
    char buff[BUFFLEN];
    time_t now;
    int count = 0;

    printf("handle_connect ss=%d ,pid=0x%x\n",ss, getpid());

    int sc;
    while(1)
    {
        errno = 0;
        sc = accept(ss,(struct sockaddr*)&from,&len);
        if(sc==-1)
        {
            printf("accept sc=%d errno=%d,msg=%s\n",sc,errno,strerror(errno));
            exit(1);
        }

        static char tempStr[32] = {0};
        inet_ntop(AF_INET,&(from.sin_addr),tempStr,sizeof(tempStr));
        printf("[pid=0x%x]handle_connect ss=%d,sc=%d connect from %s:%u\n", getpid(),ss,sc,tempStr,ntohs(from.sin_port));

        memset(buff,0,BUFFLEN);
        n=recv(sc,buff,BUFFLEN,0);


        if(n>0 && !strncmp(buff,"TIME",4))
        {
            printf("[pid=0x%x]recv data ss=%d,sc=%d  port=%u data=[%s], count=%d\n",getpid(),ss,sc,ntohs(from.sin_port),buff,++count);
            memset(buff,0,BUFFLEN);
            now=time(NULL);
            sprintf(buff,"[%24s]\r\n",ctime(&now));
            send(sc,buff,strlen(buff),0);
        }
        close(sc);
    }

}
void sig_int(int num)
{
    exit(1);
}
int tcp_main(void)
{
    int ss;
    struct sockaddr_in local;
    signal(SIGINT,sig_int);


    ss=socket(AF_INET,SOCK_STREAM,0);
    printf("ss=%d\n",ss);

    memset(&local,0,sizeof(local));
    local.sin_family = AF_INET;
    local.sin_addr.s_addr=htonl(INADDR_ANY);
    local.sin_port = htons(SERVER_PORT);



    int res = bind(ss,(struct sockaddr*)&local,sizeof(local));
    printf("bind res=%d\n",res);

    res = listen(ss,BACKLOG);
    printf("listen res=%d\n",res);

    pid_t pid[PIDNUMB];
    int i = 0;
    for(i =0;i<PIDNUMB;i++)
    {
        pid[i]=fork();
        if(pid[i]==0)
        {
            tcp_handle_connect(ss);
        }
    }
    while(1);

    return 0;
}

int main(void)
{
    tcp_main();
    return 0;
}

2.3.客户端发送

在这里插入图片描述
在这里插入图片描述

2.4.运行结果

ss=3
bind res=0
listen res=0
handle_connect ss=3 ,pid=0x194c3
handle_connect ss=3 ,pid=0x194c2
[pid=0x194c3]handle_connect ss=3,sc=4 connect from 192.168.10.2:4001
[pid=0x194c2]handle_connect ss=3,sc=4 connect from 192.168.10.2:4002
[pid=0x194c3]recv data ss=3,sc=4  port=4001 data=[TIMEA], count=1
[pid=0x194c2]recv data ss=3,sc=4  port=4002 data=[TIMEB], count=1
[pid=0x194c3]handle_connect ss=3,sc=4 connect from 192.168.10.2:4001
[pid=0x194c3]recv data ss=3,sc=4  port=4001 data=[TIMEA], count=2
[pid=0x194c2]handle_connect ss=3,sc=4 connect from 192.168.10.2:4001
[pid=0x194c2]recv data ss=3,sc=4  port=4001 data=[TIMEA], count=2
[pid=0x194c3]handle_connect ss=3,sc=4 connect from 192.168.10.2:4001
[pid=0x194c3]recv data ss=3,sc=4  port=4001 data=[TIMEA], count=3
[pid=0x194c2]handle_connect ss=3,sc=4 connect from 192.168.10.2:4001
[pid=0x194c2]recv data ss=3,sc=4  port=4001 data=[TIMEA], count=3

2.5.结果分析

1、两个客户端连接,fork出来的进程都能进行处理;
2、对于同一个客户端连接,fork出来的进行能够被调度处理到;
可以想象同一个端口存在一个连接队列。备注:在早期的linux版本,存在惊群问题,即会唤醒队列中所有进程,造成性能问题,貌似新版本内核解决方案为只唤醒等待队列上的第一个进程或者线程。
3、不同进程的文件描述符可以相同,但代表不同的设备或者文件。

备注:

1、基础代码来源于《linux网络编程 第二版》宋敬彬等编著;

linux多线程+UDP网络通信(总结+程序) linux系统下建立多线程程序设计,完成UDP网络通信的发送与接收,包括总结与源代码,实测效果可见链接https://blog.youkuaiyun.com/zxp121127/article/details/78506081 立即下载

相关推荐

JHU ICBM DTI Atlas纤维束模板介绍

JHU ICBM DTI atlas 纤维束的定位与功能介绍

machinelearning_er的博客 6423

TCP/UDP底层实现(c实现)の四

linux下多线程服务和windows多线程

jack的博客 2647

ESP32S3开发板玩转多语言AI对话:小智语音机器人粤语/日语/韩语实测

本文基于正点原子ESP32S3开发板,实测了“小智AI”语音机器人的多语言对话能力。项目巧妙整合云端AI与嵌入式硬件,实现了对粤语、日语、韩语等语言的实时识别与合成,为开发者和爱好者提供了一个低成本、可玩性高的跨语言人机交互开发平台。

h9j8k7l6m5n的博客 538

Linux C/C++ 多线程TCP/UDP服务器 (监控系统状态)

Linux环境中实现并发TCP/IP服务器。多线程在解决方案中提供了并发性。由于并发性,它允许多个客户端同时连接到服务器并与服务器交互。

chen1415886044的博客 2735

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(四)-无人机系统(UAS)命令与控制(C2)通信用例

UTM向5G网络提供无人机系统C2通信所需的信息,例如服务类别、无人机系统服务的流量类型、授权的无人机系统服务所需的QoS以及无人机系统服务的订阅。遵循模型B的网络辅助C2模型,为了确保UAS操作的C2通信的服务可用性和可靠性,特别是当无人机在操作员的视线之外(BLOS)飞行时,为无人机提供支持冗余的C2通信链路。如果需要创建额外的C2通信连接或更改现有数据连接的配置以进行C2通信,则5G网络会根据无人机系统的授权服务信息和C2通信中所需的QoS和优先级,修改或分配一个或多个C2通信流量的QoS流。

u011376987的博客 2051

MacOS上如何修改jupyter book的默认打开地址以及如何复制文件路径

记点笔记,才换新系统小半年,还是不太熟悉,所以记录一下笔记,感觉之后也会用到,希望能帮到你们。主要内容是:修改jupyter的默认地址以及复制文件路径。

魔仙的博客 1978

Linux高并发服务器开发—UDP、广播、组播、本地socket

udp服务端 udp客户端 UDP通信的现象: 向子网中多台计算机发送消息,并且子网中所有的计算机都可以接收到发送方发送的消息,每个广 播消息都包含一个特殊的IP地址,这个IP中子网内主机标志部分的二进制全部为1。 a.只能在局域网中使用。 b.客户端需要绑定服务器广播使用的端口,才可以接收到广播消息。 广播服务端 广播客户端 组播(多播)——了解 单播地址标识单个 IP 接口,广播地址标识某个子网的所有 IP 接口,多播地址标识一组 IP 接口。单播和广播是寻址方案的两个极端(要么单个要么全部)

梅山 750

YOLOv12改进策略【独家融合改进】| SPD-Conv+PPA 再次提升模型针对小目标的特征提取能力

SPD-Conv是一种新的 CNN 构建模块,用于替代传统 CNN 架构中使用的步长卷积(strided convolution)和池化(pooling)层,它由空间到深度(Space-to-depth,SPD)层和非步长卷积(non - strided convolution)层组成。

Limiiiing的博客 1028

Linux网络编程 | UDP服务器

文章目录一、UDP1.1 简介1.2 常用函数‘1.2.1 recvfrom1.2.2 recv1.2.3 send1.2.4 sendto二、组播 一、UDP 1.1 简介 UDP在传输过程中,不需要像TCP需要三次握手建立连接,从而提大幅提高通信间的效率,实时性强且开销小。但通信的稳定性和正确率却得不到保证;故被称为无连接的不可靠报文传递; 故在使用该协议进行传输时,为了保证数据的正确性,我们需要在应用层添加辅助校验协议来填补这个不足; 当然,UDP没有类似TCP的滑动窗口机制,故缓冲区被填满

weixin_45926547的博客 2188

使用 MATLAB/Simulink + Simscape Electrical 来构建一个CCHP微电网与新能源协同运行的模型

随着能源需求的增长和对环境保护要求的提高,冷热电联供(Combined Cooling, Heating and Power, CCHP)系统作为一种高效的分布式能源解决方案,越来越受到关注。CCHP系统通过利用一次能源同时产生电力、制冷和供热,实现了能源的梯级利用,提高了能源使用效率。结合太阳能、风能等可再生能源,可以进一步增强系统的灵活性和环保性。本文将详细介绍如何使用来构建一个CCHP微电网与新能源协同运行的模型,并通过仿真分析其性能表现。本文介绍了如何使用构建一个。

xiaoheshang_123的博客 141

<PLC><汇川>汇川PLC基于EtherCat协议使用转矩模式控制SV630N伺服驱动电机

本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。除了PLC为主要内容外,PLC相关元器件如触摸屏(HMI)、交换机等工控产品,如果有值得记录的内容,也会添加进来。

用沸腾的热血,支付我们的人生吧! 4158

Linux C++ 多线程高并发服务器实战项目一

1、项目介绍1、按照包头+包体的格式收发数据包,解决粘包的问题 2、非常完整的多线程高并发服务器 3、根据收到数据包执行,不同的业务逻辑函数 用到的技术: epoll高并发通讯技术,用的是水平触发【LT】水平触发模式 通过线程池技术处理业务逻辑 多线程、之间同步技术使用,互斥量、和条件变量 一个master管理进程,多个w...

cnzzs的博客 807

ardupilot开发 --- 避障篇

适配ardupilot的雷达避障功能开发,使用低成本雷达思岚科技系列雷达,配置简单,灵敏度高,障碍物检测范围不低于30m。

记录老板的每次pua,分享领导每天的毒鸡汤... 4301

linux学习之多高并发服务器篇(一)

高并发服务器 高并发服务器 并发服务器开发 1.多进程并发服务器  使用多进程并发服务器时要考虑以下几点: 父最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符) 系统内创建进程个数(内存大小相关) 进程创建过多是否降低整体服务性能(进程调度) server /* server.c */ #include <...

anlei20110504的博客 138

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Linux高并发服务器开发(一)-说明

Linux下C++开发的轻量级、高性能、高并发web服务器。《UNIX环境高级编程 第3版》《LINUX/UNIX系统编程》《LINUX内核设计与实践》《UNIX网络编程 第3版》《TCP/IP详解 卷1》《计算机网络 第7版》

Oafz的博客 454

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

linux下c控制socket并发,epoll+socket实现并发服务器 Linux C(版本一)

#include/***********************************************epoll_socket 实现并发服务器(简易)* 这个只是一个接收数据的例子,还有很多小细节没有处理,比如客户端断开后,从epoll中删除fd(以后的版本再更新)*作者:邱于涵*2017年6月23日21:14:10*QQ:1031893464**********************...

weixin_39942318的博客 318

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Linux高并发服务器开发(一)Linux系统编程入门

库文件是计算机上的一类文件,可以简单的把库文件看成一种代码仓库,提供给使用者一些可以直接拿来用的变量、函数或类库是一种特殊的程序,编写库的程序和编写一般的程序区别不大,只是库不能单独运行库文件有两种:静态库和动态库(共享库)。静态库在程序的链接阶段被复制到了程序中;动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用库的好处是:1、代码保密;2、方便部署和分发。

qq_44566415的博客 386

Linux回射服务器(一):多进程实现并发

建立连接后创建一个进程来处理每个连接 使用fork()函数创建子进程 服务器端:#include<sys/types.h> #include<sys/socket.h> #include<stdio.h> #include<netinet/in.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> #include<stdl

Mimahoo的博客 1043

Linux高并发服务器开发—网络编程(一)

网卡是一块被设计用来允许计算机在计算机网络上进行通讯的计算机硬件,又称为网络适配器或网 络接口卡NIC。其拥有 地址,属于 OSI 模型的第 层,它使得用户可以通过电缆或无线相互 连接。每一个网卡都有一个被称为 MAC 地址的独一无二的 位串行号。 网卡的主要功能1.数据的封装与解封装2.链路管理3.数据编码与译码MAC 地址(Media Access Control Address),直译为媒体存取控制位址,也称为局域网地址、以太网地址、物理地址或硬件地址,它是一个用来的位址,由网络设备制造商生产时

梅山 762

linux网络编程:高并发服务器模型(一) 多进程 多线程

一、概述

Jags的博客 387

linux(一)------多进程并发服务器实现(fork)

本文用fork()函数实现一个多进程并发服务器

tuoniaoatuoniao的博客 2301

Linux高并发服务器开发—进程间通信(一)

1、匿名管道2、有名管道3、信号4、消息队列5、共享内存6、信号量7、Socket 循环队列:线性队列变成环形队列,可以覆盖写数据。 同时发送和接收: 匿名管道数据基本单向流动,不会出现双向流动,避免发生错误。子进程: ps aux, 子进程结束后,将数据发送给父进程 父进程:获取到数据,过滤 pipe() execlp() 子进程将标准输出 stdout_fileno 重定向到管道的写端。 dup2 管道的读写特点和管道设置为非阻塞 管道的读写特点 使用管道时,需要注意以下几种特殊的情况(假设

梅山 350

Linux C/C++ 开发(学习笔记十一 ):TCP服务器(并发网络网络编程 一请求一线程)

Linux C/C++ 开发(学习笔记十一 ):TCP服务器(并发网络网络编程 一请求一线程)一、TCP服务器(一请求一线程) 的原理二、完整代码三、测试四、补充 一、TCP服务器(一请求一线程) 的原理 通过sockfd绑定(bind)和监听(listen),每过来一个客户端就接受(accept),并创建一个clientfd,每个clientfd,占据一个线程。 每个线程执行 接受(recv)并printf的任务。 具体的监听过程 二、完整代码 #include<sys/socket.h>

菊头蝙蝠的博客 2532
上一篇: linux线程调度策略和优先级使用
下一篇: linux并发服务器(二)
skytering
博客等级 码龄18年 33粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值