1.服务器处理并发的必要性

如下图所示, 当一个客户端与服务器建立连接以后,服务器端 accept()返回,进而准备循环接收客户端发过来的数据。如果客户端暂时没发数据,服务端会在 recv()处阻塞。此时,其他客户端向服务器发起连接后,由于服务器阻塞了,无法执行 accept()接受连接,也就是其他客户端发送的数据,服务器无法读取。服务器也就无法并发同时处理多个客户端。

这个问题可以通过引入多线程和多进程来解决。服务端接受一个客户端的连接后,创建一个线程或者进程,然后在新创建的线程或进程中循环处理数据。主线程(父进程)只负责监听客户端的连接,并使用 accept()接受连接,不进行数据的处理。如下图所示:

2.多线程处理并发

服务器端示例代码 thread_server.c 如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<pthread.h>void* pthread_fun(void* arg)
{int c = *(int*)arg;while(1){char buff[128] = {0};int n = recv(c,buff,127,0);if(n <= 0){break;}printf("recv(%d)=%s\n",c,buff);send(c,"OK",2,0);}
}int main()
{int sockfd = socket(AF_INET,SOCK_STREAM,0);assert(sockfd != -1);struct sockaddr_in saddr,caddr;memset(&saddr,0,sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);saddr.sin_addr.s_addr = inet_addr("127.0.0.1");int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));assert(res != -1);listen(sockfd,5);while(1){int len = sizeof(caddr);int c = accept(sockfd,(struct sockaddr*)&caddr,&len);if(c < 0){continue;}printf("accept = %d\n",c);pthread_t id;pthread_create(&id,NULL,pthread_fun,(void*)&c);}close(sockfd);exit(0);
}

运行结果
打开服务端,获取客户端发送的消息:

分别打开三个客户端,并且输入值:


3.多进程处理并发

服务器端示例代码process_server.c 如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<signal.h>void recv_fun(int c, struct sockaddr_in caddr)
{while(1){char buff[128] = {0};int n = recv(c,buff,127,0);if(n <= 0){break;}printf("%s:%d  %s\n",inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port),buff);send(c,"OK",2,0);}
}void sigfun()
{wait(NULL);
}int main()
{signal(SIGCHLD,sigfun);//子进程结束会给父进程发送SIGCHLD信号,sigfun处理int sockfd = socket(AF_INET,SOCK_STREAM,0);assert(sockfd != -1);struct sockaddr_in saddr,caddr;memset(&saddr,0,sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);saddr.sin_addr.s_addr = inet_addr("127.0.0.1");//将一个点分十进制的IP转换成一个长整型数int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));assert(res != -1);listen(sockfd,5);while(1){int len = sizeof(caddr);int c = accept(sockfd,(struct sockaddr*)&caddr,&len);assert(c != -1);printf("%s:%d Link Sucess\n",inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));//inet_ntoa是将网络地址转化为“.”隔的字符串格式pid_t pid = fork();assert(pid != -1);if(pid == 0){recv_fun(c,caddr);exit(0);//必须结束子进程,否则会有多个进程调用accept}else{close(c);//父子进程都要关闭c}}
}

运行结果
我们用循环发送的客户端连接示例:

对应的两个客户端发送情况:

socket网络编程——多进程、多线程处理并发相关推荐

  1. Python: Socket网络编程,多线程处理小Demo

    一个简单的例子,深入研究一下socket的多线程处理任务 Server端: #!/usr/bin/env python #encoding:utf8 # # 注意:定义encoding时必须在第二行i ...

  2. 多实例多进程网络编程PHP,php socket网络编程基础知识(四):多进程

    标签:status   传递   windows   返回   修改   队列   _for   响应   关联 说明 php在web编程时是不需要考虑多进程的,但整个php流程是涉及到多进程的,只不 ...

  3. Linux C++/Java/Web/OC Socket网络编程

    一,Linux C++ Socket网络编程 1.什么是TCP/IP.UDP? TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制 ...

  4. python开发之Socket网络编程

    python开发之Socket网络编程 一.SOCKET基础 二.SOCKET通信流程 1. 流程描述: 2. 相关方法及参数介绍: 三.实例(屌丝追女神的故事) 1. 故事1:(一次通信) 2. 故 ...

  5. Linux 网络编程——socket 网络编程

    文章目录 一.网络基础 TCP/UDP对比 TCP/IP协议族体系 socket IP地址 IP地址转化API inet_addr() inet_aton() inet_ntoa() inet_pto ...

  6. Socket网络编程--简单Web服务器(6)

    本来是想实现ssl连接的,但是弄了好久都不成功,就索性不做了,等以后有能力再做了.所以这一小节就是本次的最后一节了.就简单的说几个注意点. 1.加个配置文件 使用单例模式,使用一个类,该类保存一些信息 ...

  7. Python之旅Day8 socket网络编程

    socket网络编程 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示"打开了一个网络链接",而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定 ...

  8. Day09: socket网络编程-OSI七层协议,tcp/udp套接字,tcp粘包问题,socketserver

    今日内容:socket网络编程     1.OSI七层协议     2.基于tcp协议的套接字通信     3.模拟ssh远程执行命令     4.tcp的粘包问题及解决方案     5.基于udp协 ...

  9. Python面向对象进阶和socket网络编程

    写在前面 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese:def __init__(self, ...

最新文章

  1. Struts2-2.了解struts.xml的查找顺序
  2. Python进程multiprocessing. Process()的使用
  3. picture of web
  4. python参数传递时不构造新数据对象_关于函数的参数传递(parameter passing),以下选项中描述错误的是_学小易找答案...
  5. 02 - java 标识符命名规范
  6. python while语法结构_python语法之流程控制(if while for)
  7. 【算法】【JAVA】冒泡排序
  8. 解决maven项目jdbc报错:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
  9. 学习template算法以及改进(一)
  10. laydate 周_宝来屋:5天168万!海盐周大生新店如何赢过竞品实现可持续化客流-广告随意贴...
  11. SpringMVC强大的数据绑定(2)——第六章 注解式控制器详解——跟着开涛学SpringMVC...
  12. python 实现A星算法
  13. Win 10 版NVIDIA GeForce GTX 1060显卡驱动的下载及飞桨(Paddle)的安装
  14. poi操作word,写入一个图片,并且设置其大小,以及图片和base64之间的互相转换,以及表格内容替换和插入
  15. c# 连接 oracle数据库字符集为us7ascii的问题,实验了好几个方案 成功了
  16. 数位板使用技巧_保护您的眼睛技巧,以帮助防止数位眼疲劳
  17. 华为手机android是什么意思,华为手机的英文文件夹是什么意思?哪些可以删除?今天总算知道了...
  18. IDE工具(42) Alibaba Cloud Toolkit 一键部署插件使用入门
  19. 【技术邻】聊一聊材料应力-应变曲线
  20. 【提交】commit

热门文章

  1. 实现文件上传进度条功能
  2. [网络安全自学篇] 八十一.WHUCTF之WEB类解题思路WP(文件上传漏洞、冰蝎蚁剑、反序列化phar)
  3. 【数据结构与算法】之深入解析“路径总和III”的求解思路与算法示例
  4. HarmonyOS之常用组件WebView的使用
  5. setdefaultencoding函数使用详解
  6. 10.2.2 选择器
  7. Go + Excel 学习 Excelize
  8. 【Linux】一步一步学Linux——dig命令(160)
  9. 【Linux】一步一步学Linux——chmod命令(110)
  10. [Qt教程] 第43篇 进阶(三)对象树与拥有权