00. 目录

文章目录

  • 00. 目录
  • 01. 概述
  • 02. 多线程服务器
  • 03. 多线程服务器实现思路
  • 04. 多线程服务器实现
  • 05. 附录

01. 概述

服务器设计技术有很多,按使用的协议来分有 TCP 服务器UDP 服务器,按处理方式来分有循环服务器并发服务器

循环服务器与并发服务器模型

在网络程序里面,一般来说都是许多客户对应一个服务器(多对一),为了处理客户的请求,对服务端的程序就提出了特殊的要求。

目前最常用的服务器模型

  • 循环服务器:服务器在同一时刻只能响应一个客户端的请求。
  • 并发服务器:服务器在同一时刻可以响应多个客户端的请求。

02. 多线程服务器

多线程服务器是对多进程的服务器的改进,由于多进程服务器在创建进程时要消耗较大的系统资源,所以用线程来取代进程,这样服务处理程序可以较快的创建。据统计,创建线程与创建进程要快 10100 倍,所以又把线程称为“轻量级”进程。线程与进程不同的是:一个进程内的所有线程共享相同的全局内存、全局变量等信息,这种机制又带来了同步问题

03. 多线程服务器实现思路

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bwL4urkX-1595993960681)(assets/image-20200729113010149.png)]

04. 多线程服务器实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>/************************************************************************
函数名称:    void *client_process(void *arg)
函数功能:    线程函数,处理客户信息
函数参数:    已连接套接字
函数返回:    无
************************************************************************/
void *client_process(void *arg)
{int recv_len = 0;char recv_buf[1024] = ""; // 接收缓冲区int connfd = (int)arg; // 传过来的已连接套接字// 接收数据while((recv_len = recv(connfd, recv_buf, sizeof(recv_buf), 0)) > 0){printf("recv_buf: %s\n", recv_buf); // 打印数据send(connfd, recv_buf, recv_len, 0); // 给客户端回数据}printf("client closed!\n");close(connfd);    //关闭已连接套接字return    NULL;
}//===============================================================
// 语法格式: void main(void)
// 实现功能: 主函数,建立一个TCP并发服务器
// 入口参数: 无
// 出口参数: 无
//===============================================================
int main(int argc, char *argv[])
{int sockfd = 0;               // 套接字int connfd = 0;int err_log = 0;struct sockaddr_in my_addr;  // 服务器地址结构体unsigned short port = 8080; // 监听端口pthread_t thread_id;printf("TCP Server Started at port %d!\n", port);sockfd = socket(AF_INET, SOCK_STREAM, 0);   // 创建TCP套接字if(sockfd < 0){perror("socket error");exit(-1);}bzero(&my_addr, sizeof(my_addr));       // 初始化服务器地址my_addr.sin_family = AF_INET;my_addr.sin_port   = htons(port);my_addr.sin_addr.s_addr = htonl(INADDR_ANY);printf("Binding server to port %d\n", port);// 绑定err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));if(err_log != 0){perror("bind");close(sockfd);        exit(-1);}// 监听,套接字变被动err_log = listen(sockfd, 10);if( err_log != 0){perror("listen");close(sockfd);     exit(-1);}printf("Waiting client...\n");while(1){char cli_ip[INET_ADDRSTRLEN] = "";       // 用于保存客户端IP地址struct sockaddr_in client_addr;           // 用于保存客户端地址socklen_t cliaddr_len = sizeof(client_addr);   // 必须初始化!!!//获得一个已经建立的连接 connfd = accept(sockfd, (struct sockaddr*)&client_addr, &cliaddr_len);                             if(connfd < 0){perror("accept this time");continue;}// 打印客户端的 ip 和端口inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);printf("----------------------------------------------\n");printf("client ip=%s,port=%d\n", cli_ip,ntohs(client_addr.sin_port));if(connfd > 0){//由于同一个进程内的所有线程共享内存和变量,因此在传递参数时需作特殊处理,值传递。pthread_create(&thread_id, NULL, (void *)client_process, (void *)connfd);  //创建线程pthread_detach(thread_id); // 线程分离,结束时自动回收资源}}close(sockfd);return 0;
}

注意,上面例子给线程传参有很大的局限性,最简单的一种情况,如果我们需要给线程传多个参数,这时候我们需要结构体传参,这种值传递编译都通不过,这里之所以能够这么值传递,因为在32位系统中int 长度时 4 个字节, void * 长度也是 4 个字节。

05. 附录

【Linux】一步一步学Linux网络编程教程汇总

【Linux网络编程】并发服务器之多线程模型相关推荐

  1. Linux io模型及函数调用,Linux 网络编程的5种IO模型:信号驱动IO模型

    Linux 网络编程的5种IO模型:信号驱动IO模型 背景 这一讲我们来看 信号驱动IO 模型. 介绍 情景引入: 在信号驱动IO模型中,当用户线程发起一个IO请求操作,会给对应的socket注册一个 ...

  2. 【Linux网络编程】并发服务器之select模型

    00. 目录 文章目录 00. 目录 01. 概述 02. I/O复用技术概述 03. select模型服务器实现思路 04. select模型服务器实现 05. 附录 01. 概述 服务器设计技术有 ...

  3. 【Linux网络编程】并发服务器之多进程模型

    00. 目录 文章目录 00. 目录 01. 概述 02. 多进程并发服务器 03. 多进程并发服务器实现思路 04. 多进程并发服务器实现 05. 附录 01. 概述 服务器设计技术有很多,按使用的 ...

  4. Linux 网络编程四(socket多线程升级版)

    //网络编程--客户端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...

  5. Linux 网络编程——并发服务器的三种实现模型

    服务器设计技术有很多,按使用的协议来分有 TCP 服务器和 UDP 服务器,按处理方式来分有循环服务器和并发服务器. 循环服务器与并发服务器模型 在网络程序里面,一般来说都是许多客户对应一个服务器(多 ...

  6. Linux网络编程 | 并发模式:半同步/半异步模式、领导者/追随者模式

    文章目录 同步与异步 半同步/半异步模式 变体:半同步/半反应堆模式 改进:更高效的半同步/半异步模式 领导者/追随者模式 组件 :句柄集.线程集.事件处理器 并发模式是指I/O处理单元和多个逻辑单元 ...

  7. 【Linux】一步一步学Linux网络编程教程汇总(更新中......)

    00. 目录 文章目录 00. 目录 01. 基础理论知识 02. 初级编程 03. 高级编程 04. LibEvent库 05. 06. 07. 01. 基础理论知识 [Linux网络编程]网络协议 ...

  8. 【Linux网络编程】循环服务器之TCP模型

    00. 目录 文章目录 00. 目录 01. 概述 02. TCP循环服务器实现方法 03. TCP循环服务器模型 04. TCP循环服务器实现 05. 附录 01. 概述 服务器设计技术有很多,按使 ...

  9. 【Linux网络编程】循环服务器之UDP循环模型

    00. 目录 文章目录 00. 目录 01. 概述 02. UDP循环服务器的实现方法 03. UDP循环服务器模型 04. UDP循环服务器实现 05. 附录 01. 概述 服务器设计技术有很多,按 ...

最新文章

  1. 【pytorch】nn.conv1d的使用
  2. ae中心点重置工具_不懂这些知识,你的AE白学了!
  3. 非标准配置linux,剖析非标准波特率的设置和使用于Linux操作系统中
  4. golang经典书籍--Go语言圣经
  5. 【Linux】28.Linux脚本判断是否安装了某软件
  6. 【PAT乙级】1089 狼人杀-简单版 (20 分)
  7. 2021.02.01 Visual QA论文阅读
  8. 数据库异常关闭后无法启动问题处理
  9. 默认情况下安装的应用程序C盘后提示权限不足,当你开始介意。。。
  10. 360浏览器清凉新版让手机解暑
  11. (十五)final关键字
  12. Windows系统服务器IIS7.5 Asp.net支持10万请求的设置方法
  13. linux下怎么解压tar.gz,linux下怎么解压.tar.gz .tar.bz2命令
  14. ele表单验证的数字的坑
  15. 由边际成本引发的思考
  16. 2021-2027全球与中国地质与矿山规划软件市场现状及未来发展趋势
  17. 你玩的英雄在比赛中发挥如何呢?
  18. JavaFX - 制作登录窗口及界面跳转
  19. Essential singularity
  20. R语言第十讲 逻辑斯蒂回归

热门文章

  1. pytest入门学习(2)
  2. RESTORE DATABASE的standby选项
  3. 用javascript实现自动隐藏页面字段
  4. linux 同步 多终端,Linux系统如何实现不同终端间的同步
  5. 利用java格里高利公式求圆周率_用格里高利公式求π的近似值
  6. Java黑皮书课后题第8章:**8.11(游戏:九个硬币的正反面)一个3*3的矩阵中放置了9个硬币,这些硬币有些面朝上有朝下。1表示正面0表示反面,每个状态使用一个二进制数表示。使用十进制数表示状态
  7. 对C#面向对象三大特性的一点总结
  8. Eclipse配置关联Tomcat并运行项目
  9. JS实现全选、反选、不选
  10. win10被微软流氓更新后编译基于visual Studio的web项目报[ArgumentOutOfRangeException: 指定的参数已超出有效值的范围...