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

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

一、TCP服务器(一请求一线程) 的原理

通过sockfd绑定(bind)和监听(listen),每过来一个客户端就接受(accept),并创建一个clientfd,每个clientfd,占据一个线程。

每个线程执行 接受(recv)并printf的任务。

具体的监听过程

二、完整代码

#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<unistd.h>
#define BUFFER_LENGTH 1024
void* client_routine(void* arg){
    int clientfd=*(int*)arg;
    while(1){
        char buffer[BUFFER_LENGTH]={0};
        int len=recv(clientfd,buffer,BUFFER_LENGTH,0);//阻塞就会挂起
        if(len<0){//阻塞io不存在len<0因为它会挂起在recv时刻,一旦发生,就说明出错了
            close(clientfd);
            break;
        }else if(len==0){//disconnect (读取数据为0就说明客户端断开连接了)
            close(clientfd);
            break;
        }else{
            printf("Recv:%s,%d bytes\n",buffer,len);
        }
    }
}
int main(int argc,char** argv){
    if(argc<2){
        printf("Param Error\n");
        return -1;
    }
    int port=atoi(argv[1]);
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    sockaddr_in addr;
    memset(&addr,0,sizeof(sockaddr_in));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    addr.sin_addr.s_addr=INADDR_ANY;//0.0.0.0 泛指本机的意思
    if(bind(sockfd,(sockaddr*)&addr,sizeof(sockaddr_in))<0){//绑定
        perror("bind");
        return 2;
    }
    if(listen(sockfd,5)<0){//监听(最多可以排队5个)
        perror("listen");
        return 3;
    }
    //一请求 一线程
    while(1){
        sockaddr_in client_addr;
        memset(&client_addr,0,sizeof(sockaddr_in));
        socklen_t client_len = sizeof(client_addr);
        int clientfd = accept(sockfd,(sockaddr*)&client_addr,&client_len);//接受一个客户,并将它的ip存到client_addr中,并形成了一个客户端fd
        pthread_t thread_id;
        pthread_create(&thread_id,NULL,client_routine,&clientfd);//为每个clientfd分配一个线程
    }
    return 0;
}

编译指令

g++ tcp_sever.cpp -o tcp_sever -lpthread

三、测试

执行,设置服务器端口为8888

./tcp_server 8888

打开NetAssist.exe

选择TCP Client,远程主机是自己的服务器的ip:端口号

点击连接

然后在下方可以发送数据了,点击发送

在服务器端可以接受到数据

四、补充

多个客户端,如何区分哪个客户端发送的?

sockfd是解决不了的

通过定义应用协议来解决,比如说在发送的同时也发送 用户id

一请求一线程 的缺点:

随着客户端越来越多 (比如100w)

不合适用一请求一线程的方式。

posix thread 8M。 1G内存 —》128个。比较有限。

现在已经弃用了,而选用epoll的方式


相关文章
|
2月前
|
网络协议
端口最多只有65535个,为什么服务器能承受百万并发
服务器通过四元组(源IP、源端口、目标IP、目标端口)识别不同TCP连接,每条连接对应独立socket。数据包携带四元组信息,服务端据此查找对应socket进行通信。只要四元组任一元素不同,即视为新连接,可创建独立socket。资源充足时,单进程可支持百万级并发连接,socket与端口非一一对应。
157 10
端口最多只有65535个,为什么服务器能承受百万并发
|
2月前
Vite使用svg-企业级开发(支持本地svg和网络svg渲染)
本教程介绍如何在Vite项目中集成SVG图标插件。首先安装`vite-plugin-svg-icons`,配置插件指向SVG图标目录,并注册全局组件。接着创建SVG图标组件,支持内部图标与外部图片展示。通过简单配置,即可在页面中灵活使用各类SVG图标,提升开发效率。
143 0
|
5月前
|
JSON 中间件 Go
Go 网络编程:HTTP服务与客户端开发
Go 语言的 `net/http` 包功能强大,可快速构建高并发 HTTP 服务。本文从创建简单 HTTP 服务入手,逐步讲解请求与响应对象、URL 参数处理、自定义路由、JSON 接口、静态文件服务、中间件编写及 HTTPS 配置等内容。通过示例代码展示如何使用 `http.HandleFunc`、`http.ServeMux`、`http.Client` 等工具实现常见功能,帮助开发者掌握构建高效 Web 应用的核心技能。
314 61
|
5月前
|
开发者
鸿蒙仓颉语言开发教程:网络请求和数据解析
本文介绍了在仓颉开发语言中实现网络请求的方法,以购物应用的分类列表为例,详细讲解了从权限配置、发起请求到数据解析的全过程。通过示例代码,帮助开发者快速掌握如何在网络请求中处理数据并展示到页面上,减少开发中的摸索成本。
鸿蒙仓颉语言开发教程:网络请求和数据解析
|
5月前
|
监控 安全 网络协议
恶意软件无处逃!国内版“Manus”AiPy开发Windows沙箱工具,进程行为+网络传输层级监控! 头像 豪气的
NImplant.exe 是一款后渗透测试工具,可实现远程管理与持久化控制。其优点包括无文件技术、加密通信和插件扩展,但也存在被检测风险及配置复杂等问题。为深入分析其行为,我们基于 aipy 开发了 Windows 沙箱工具,针对桌面上的 NImplant.exe 进行多维度分析,涵盖进程行为、网络连接(如 TCP 请求、目标 IP/域名)、文件控制等,并生成传输层监控报告与沙箱截图。结果显示,aipy 工具响应迅速,报告清晰易读,满足分析需求。
|
网络协议 安全 Java
Java中的网络编程:Socket编程详解
Java中的网络编程:Socket编程详解
|
Java 大数据
如何在Java中进行网络编程:Socket与NIO
如何在Java中进行网络编程:Socket与NIO
|
Java API 网络安全
Java网络编程入门
Java网络编程入门
|
Java API 开发者
Java网络编程基础与Socket通信实战
Java网络编程基础与Socket通信实战
|
网络协议 安全 Java
Java中的网络编程:Socket编程详解
Java中的网络编程:Socket编程详解

热门文章

最新文章