【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端

这篇具有很好参考价值的文章主要介绍了【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一,往期文章

二,代码实现

关键代码

完整代码

运行效果


一,往期文章

【高并发网络通信架构】1.Linux下实现单客户连接的tcp服务端

二,代码实现

关键代码

  • 因为accept是阻塞等待客户端连接,当客户端连接成功后才会执行accept后面的代码,所以为实现多个客户端连接,第一步是将accept放在master循环里。【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端,架构,tcp/ip,网络
  • recv是阻塞型函数,如果不将recv的相关代码放到线程里去,会导致客户端无法与服务端通信。【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端,架构,tcp/ip,网络​​【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端,架构,tcp/ip,网络

完整代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#include <pthread.h>

#define BUFFER_LENGTH   1024

void* handleClient(void *arg)
{
    int cfd = *((int*)arg);
    while(1)    //一直循环是确保一直和服务端通信,并且recv是阻塞函数
    {
        char buffer[BUFFER_LENGTH] = {0};
        int recvLen = recv(cfd,buffer,BUFFER_LENGTH,0);
        if(recvLen < 0){
            printf("recv error code: %d codeInfo: %s\n",errno,strerror(errno));
            break;
        }else if(recvLen == 0){
            //客户端断开连接
            printf("client fd %d disconnect\n",cfd);
            close(cfd);     //关闭客户端文件描述符,释放资源
            break;
        }else{
            printf("recv fd %d data: %s\n",cfd,buffer);
            send(cfd,buffer,recvLen,0);    //将接收到的数据重新发给客户端
        }
    }

    //退出线程
    pthread_exit(NULL);
    return NULL;
}

int init_server(int port){
    //获取服务端fd,通常为3,前面0,1,2用于指定输入,输出,错误值
    int sfd = socket(AF_INET,SOCK_STREAM,0);

    if(-1 == sfd){
        printf("socket error code: %d codeInfo: %s\n",errno,strerror(errno));
        return -1;
    }

    struct sockaddr_in serverAddr;
    memset(&serverAddr,0,sizeof(struct sockaddr_in));
    serverAddr.sin_family = AF_INET;  //ipv4
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);   //0.0.0.0
    serverAddr.sin_port = htons(port);
    
    //绑定IP和端口号
    if(-1 == bind(sfd,(struct sockaddr*)&serverAddr,sizeof(struct sockaddr_in)))
    {
        printf("bind error code: %d codeInfo: %s\n",errno,strerror(errno));
        return -1;
    }

    //监听该套接字上的连接
    if(-1 == listen(sfd,SOMAXCONN))
    {
        printf("listen error code: %d codeInfo: %s\n",errno,strerror(errno));
        return -1;
    }

    return sfd;
}

int main(int argc,char *argv[]){

    if(argc < 2)return -1;

    int port = atoi(argv[1]);
    int sfd = init_server(port);
    printf("server fd: %d\n",sfd);
    if(sfd == -1)exit(0);

    pthread_t thread_id;
    struct sockaddr_in clientAddr;
    socklen_t clientAddrLen = sizeof(struct sockaddr_in);

    while (1)//每个服务器至少都有一个主循环
    {
        //接受新的连接请求
        int cfd = accept(sfd,(struct sockaddr*)&clientAddr,&clientAddrLen);

        //创建一个新的线程来处理客户端连接
        int flag = pthread_create(&thread_id,NULL,handleClient,(void*)&cfd);
        if(0 == flag){
            printf("client fd: %d ,thread ID: %ld start\n",cfd,thread_id);
        }else{
            perror("pthread_create");
            break;
        }

        //分离线程,让线程自行处理结束
        pthread_detach(thread_id);
    }

    close(sfd);     //关闭服务端文件描述符,释放资源
    printf("server fd %d close\n",sfd);
    
    return 0;
}

运行效果

  • 编译时记得加 -lpthread 连接到库,运行如下。【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端,架构,tcp/ip,网络

存在问题

  1. 在程序运行中,不进行客户端连接操作直接按下 Ctrl+Z 会发送一个信号(SIGTSTP)给前台运行的进程,会导致该服务端程序被挂起 (Suspended),导致我下一次在运行时会打印如下错误,说明上次运行并没有释放服务端套接字。(没有客户端连接的情况下【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端,架构,tcp/ip,网络
  2. 因为资源没有释放,导致每次要手动去杀死该挂起的进程,就很麻烦,如下。【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端,架构,tcp/ip,网络【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端,架构,tcp/ip,网络
  3. 最后执行 kill -9 394407 杀死挂起的进程。

解决方法

  • 最终的原因是程序如何退出的问题,要使程序直接退出,你可以注册一个信号处理函数来捕获 SIGTSTP 信号,并在该函数中执行退出逻辑。【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端,架构,tcp/ip,网络

问题思考文章来源地址https://www.toymoban.com/news/detail-533642.html

  • 这种实现方式对于几十几百个客户端并发连接可能没问题,但对于成千上万的客户端进行高并发连接,仍采用这种方式来处理显然是不现实的?下一章介绍。。。

到了这里,关于【高并发网络通信架构】2.引入多线程实现多客户端连接的tcp服务端的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux网络编程:socket & pthread_create()多线程 实现clients/server通信

    UNIX网络编程:socket fork()多进程 实现clients/server通信 随笔介绍了通过fork()多进程实现了服务器与多客户端通信。但除了多进程能实现之外,多线程也是一种实现方式。 重要的是,多进程和多线程是涉及操作系统层次。随笔不仅要利用pthread_create()实现多线程编程,也要理解线

    2024年02月05日
    浏览(49)
  • Linux 网络通信epoll详解( 10 ) -【Linux通信架构系列 】

    C++技能系列 Linux通信架构系列 C++高性能优化编程系列 深入理解软件架构设计系列 高级C++并发线程编程 期待你的关注哦!!! 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in reality. (1)I/O多路复

    2024年02月16日
    浏览(49)
  • 【5G通信网络架构与5G基站架构概述】

    首先,我们先来了解一下移动通信网络的基本架构,即无线网-承载网-核心网的架构,2/3/4/5G网络均是这样的构成,其中: 无线接入网(Radio Access Network) 是直接向用户终端收发信号的地面可见基站所组成的网络,就是我们日常所说的基站。 承载网 是负责将基站接收到的用户数

    2024年02月05日
    浏览(54)
  • 移动通信网络架构 1G-5G

    自20世纪80年代初第一代移动网络(1G)问世以来,移动无线通信在过去几十年里取得了许多进展。移动通信标准的这种演变是全球对更多用户和连接日益增长的需求的直接结果. 在本文中,我们将研究支撑这些移动技术的基础设施和组件——从1G一直到即将到来的5G。在本文末尾

    2023年04月12日
    浏览(44)
  • 深入理解 Hadoop (一)网络通信架构与源码浅析

    深入理解 Hadoop (一)网络通信架构与源码浅析 深入理解 Hadoop (二)HDFS架构演进 深入理解 Hadoop (三)HDFS文件系统设计实现 深入理解 Hadoop (四)HDFS源码剖析 深入理解 Hadoop (五)YARN核心工作机制浅析 深入理解 Hadoop (六)YARN核心设计理念与工作流程剖析 深入理解 Had

    2024年02月03日
    浏览(46)
  • 后端架构师必知必会系列:网络协议与通信机制

    作者:禅与计算机程序设计艺术 随着互联网的普及和互联网服务平台的崛起,越来越多的人开始了解到网络协议和通信机制。而作为后端开发工程师,掌握网络协议、通信机制对于系统的性能优化和网络安全来说至关重要。这几年,网络协议和通信机制在各个领域都得到了广

    2024年02月07日
    浏览(50)
  • 软考高级之系统架构师之数据通信与计算机网络

    80/20规则是指总流量的80%是网段内部的流量,而总流量的20%是网段外部的流量。 在划分区域之后,OSPF网络中的非主干区域中的路由器对于到外部网络的路由,一定要通过ABR(区域边界路由器)来转发,既然如此,对于区域内的路由器来说,就没有必要知道通往外部网络的详细路

    2024年02月13日
    浏览(54)
  • unity Sockets通信 使用UDP协议,设置客户端电脑网络配置,使用新线程获取数据,解决卡顿问题,

    今天调试和服务器连接,发现始终获取不到服务器的数据, 电脑和服务器都在同一局域网,仍然获取不到, 下面是电脑环境配置, 第一步: 设置网络为专用网络,然后点击配置防火墙和安全设置,关闭防火墙 (点击所连接的wifi的属性) 第二步:设置出站 入站规则 点击高

    2024年02月07日
    浏览(60)
  • 万字长文深入理解Docker镜像分层原理、容器数据卷、网络通信架构(Docker系列第2章,共3章)

    在执行docker pull时,会发现多个Pull complete 字样,就能体现分层,如果是一个文件,只会有一个Pull complete 。 概念:文件系统是计算机系统中用于组织和管理数据存储的一种方式。它定义了数据如何存储、命名、访问和修改的方式。 举例:如Windows自带的NTFS、FAT32、EXFAT,和L

    2024年04月14日
    浏览(39)
  • Qt实现TCP网络通信

    在标准C++中没有提供专门用于套接字通信的类,所以只能使用操作系统提供的基于C语言的API函数,基于这些C的API函数我们也可以封装自己的C++类。或者我们可以使用Qt框架,它提供了用于套接字通信的类(TCP、UDP)这样我们就可以直接调用相关API即可。 使用Qt提供的类进行基于

    2024年04月17日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包