我的网络观(1)——初学者的记录

简介: 本文详解如何用C语言实现“一请求一线程”TCP服务器:通过socket创建监听套接字,accept接收连接后为每个客户端创建独立线程,线程内以while循环持续recv/send,实现多客户端并发、双工、长连接通信,避免阻塞与串行等待。

如何实现一请求一线程式的tcp服务器

一.现有两台主机,分为服务器和客户端,服务器同客户端如何在网络中建立通信

本文仅描述服务端操作

1.创建一个流式套接字,绑定设定好的ip地址与端口

int sockfd = socket(AF_INET, SOCK_STREAM,0);

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(2000);
addr.sin_addr.s_addr = htonl(INADDR_ANY);

if(-1 == bind(sockfd,(struct sockaddr*)&addr,sizeof(struct sockaddr))){
    perror("bind error\n");
    return -1;
}

2.监听这个端口,并且创建好用于记录客户端ip地址和端口的变量

listen(sockfd, 10);
INFO ("listen finished\n");
struct sockaddr_in client_addr;
socklen_t len = sizeof(client_addr);

3.建立tcp连接同时创建新的套接字,用于后续的IO操作

INFO("accepting...\n");
int clientfd = accept(sockfd,(struct sockaddr*)&client_addr,&len);
INFO("accept finished\n");

image.png

4.用recv函数将从客户端传如buffer中,并将接收到的数据传回,用于检测连接是否为双工

char buffer[1024]={0};
int count = recv(clientfd,buffer,1024,0);
INFO("recv:%s,%d byte(s)\n",buffer,count);

count = send(clientfd,buffer,count,0);
INFO("SEND:%d\n",count);

至此,我们已经建立了服务端和客户端的tcp连接,并且能够实现双方的通信.
但问题来了,目前我们的tcp服务器仅能接受一个客户端发送的信息,并且每个客户端仅能发送一条消息。

TCP服务器如何和多个客户端形成稳定双工连接

很自然的想到,给建立新连接,并实现通信的过程,用一个while循环包住,这样就能不断创建新的连接。

while(1){
    INFO("accepting...\n");
    int clientfd = accept(sockfd,(struct sockaddr*)&client_addr,&len);
    INFO("accept finished\n");

    char buffer[1024]={0};
    int count = recv(clientfd,buffer,1024,0);
    INFO("recv:%s,%d byte(s)\n",buffer,count);

    count = send(clientfd,buffer,count,0);
    INFO("SEND:%d\n",count);
}

在改进完的基础上我们测试一个场景,用网络调试助手模拟三台客户端,从左到右编号1,2,3

image.png
我们按照编号顺序启动对tcp服务器的连接,下图是此时终端显示仅建立一条连接

image.png

接着我们分别发送客户端2、3号的数据,此时终端显示并未接受到任何数据

image.png

这时候我们传送客户端1的数据,数据按照连接建立的顺序实现被接收

image.png

梳理代码,如果我们只用while循环实现多连接,建立顺序靠后的连接,会由于顺序靠前连接未发送数据而被recv函数堵塞住,相互之间互相影响,这显然不是我们想要的效果。

所以选择我们创建一个线程,将收发数据放进子线程中执行

//主程序

pthread_t thid;
pthread_create(&thid,NULL,ClientThread,&clientfd);

//子线程

void *ClientThread(void *arg){
  int clientfd = *(int*)arg;
  char buffer[1024]={0};

  int count = recv(clientfd,buffer,1024,0);
  INFO("recv:%s,%d byte(s)\n",buffer,count);

  count = send(clientfd,buffer,count,0);
  INFO("SEND:%d\n",count);

 }

但现在还有一个问题,目前的所有连接只能相互通信一次,为了实现长连接,我们将子线程的收发数据操作放入while循环中

while(1){
  char buffer[1024]={0};
  int count = recv(clientfd,buffer,1024,0);
  INFO("recv:%s,%d byte(s)\n",buffer,count);

  count = send(clientfd,buffer,count,0);
  INFO("SEND:%d\n",count);
  }
}

至此,我们实现了一请求一线程式的tcp服务器。

相关文章
|
29天前
|
JavaScript 前端开发 测试技术
对比度不足、缺 alt、缺 label:把 axe-core 挂进 Playwright,用 CI 门禁拦下 WCAG 违规
本文详解如何将 axe-core 无障碍扫描集成到 Playwright 测试中,利用浏览器原生 accessibility tree 自动检测 WCAG 违规(如对比度不足、缺 alt/label、标题跳级等),并通过 CI 基线门禁拦截新增问题,让无障碍从“上线后被投诉”变为“合并前被拦截”。
对比度不足、缺 alt、缺 label:把 axe-core 挂进 Playwright,用 CI 门禁拦下 WCAG 违规
|
7天前
|
存储 人工智能 弹性计算
阿里云服务器新购、续费、升级活动:38元轻量,新购续费同价+优惠券补贴等热门活动介绍
2026年阿里云云服务器优惠政策趋于多元化、精准化与长期化:以38元轻量服务器、99元e实例、199元u1实例构成入门锚点,以"新购续费同价"消除长期成本不确定性,并以1至5年阶梯折扣(最低2.4折)鼓励深度承诺,叠加优惠券、达量返券、学生券等工具。成本优化关键不在抢最低价,而在读懂优惠边界与互斥规则,找到匹配自身节奏的最优组合。
|
20天前
|
数据采集 存储 缓存
【建站实战】用 ESA + Cloudflare 把网站月费压到接近零费用
本文以geojsoncn.com为例,详解如何用阿里云ESA(中国边缘)+ Cloudflare Workers + R2构建百度友好型静态站:ESA保障国内可达与ICP备案,Workers无服务器计算,R2低成本存储。三者协同,月成本压至约10元,兼顾SEO硬指标与极致性价比。(239字)
|
25天前
|
云安全 人工智能 安全
|
8天前
|
人工智能 弹性计算 自然语言处理
QoderWake——从桌面里的Agent到工作现场的数字员工
9月23日云栖大会,阿里Qoder产品专家耿欣发布《QoderWake:从桌面Agent到工作现场的数字员工》。该产品以“岗位角色、身份工位、培训教学、接入IM、连通系统、记忆成长”六步法,打造可入职、能履职、会进化的数字员工。已创建超10万个数字员工,服务2000+企业,助力构建人机协同的“超级组织”。
185 0
|
人工智能
上车吧,1000+claw概念域名来袭!
风口真正值钱的,从来不是最热闹的那一天,而是热闹之后,产品开始成片长出来的那一刻…
|
XML 机器学习/深度学习 JSON
|
网络协议 Java 测试技术
配置中心原理和选型:Disconf、Apollo、Spring Cloud Config 和 Nacos
学完注册中心,再看配置中心这块,感觉简单很多,因为很多知识原理是相辅相成的
10097 0
配置中心原理和选型:Disconf、Apollo、Spring Cloud Config 和 Nacos
|
开发者 黑灰产治理
阿里云开发者社区积分细则
阿里云开发者社区,积分规则、领取、过期等相关说明
4155 20