TCP并发服务器的编程实现

2023-10-27

TCP并发服务器的编程实现

1. 基于TCP的服务器编程模型

  1. 创建通信端点(套接字),返回该端点的文件描述符 sfd socket(2)
    2 )将sfd和本地的ip地址和端口号绑定 bind(2);
    3 )将sfd设置为被动连接状态,监听客户端的到来,如果有客户段的到来,将其放入到未决连接队列中.listen(2)
    while{
    4 从未决连接中取出一个处理,返回一个新的连接描述符 如果未决连接为空,阻塞等待 cfd = accept(2)
    5 从连接描述符中读取客户段的请求数据到buf中 read(2)
    6 处理buf中的数据
    7 将处理的结果写给客户端 write(2)
    8 关闭本次连接close(cfd)
    }
    2. TCP并发服务器分三个部分实现:
    1 网络编程部分:
    网络编程部分封装为一个源文件和头文件,分别是t_net.h t_net.c
    t_net.h部分源码
#ifndef __T_NET_H__
#define __T_NET_H__
#include <sys/socket.h>
#include <sys/types.h>
typedef struct sockaddr SA; 
typedef struct sockaddr_in SA4;
//socket bind
//这里将套接字的创建过程和绑定过程封装为一个函数
int bind_sock(int domain,int type,u_int16_t port);
//调用这个函数可以从未连接队列中取出一个进行处理.不会显示
//客户端的ip地址
int n_acpt(int fd);
//对比上一个函数,可以显示客户端的ip地址
int h_acpt(int fd);
//将套接字的创建 绑定 监听封装到一个函数中
int s_listen(int domain,int type,u_int16_t port,int b); 
#endif //__T_NET_H__

编写完头文件,可以把头文件移动到/usr/local/include目录下.这样include可以使用<>
t_net.c源码

#include <t_net.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
int bind_sock(int domain,int type,u_int16_t port){
    //创建一个socket设备,返回该设备的文件描述符
    SA4 serv;
    int sfd = socket(domain,type,0);
    if(sfd == -1){
        printf("%s\n",strerror(errno));
        return -1; 
    }   
    //将sfd绑定绑定本地地址
    serv.sin_family = AF_INET;
    //主机字节序到网络字节序
    serv.sin_port = htons(port);
	serv.sin_addr.s_addr = htonl(INADDR_ANY);
    int b = bind(sfd,(SA*)&serv,sizeof(serv));
    if(b == -1){
        printf("%s\n",strerror(errno));
        return -1;
    }
    return sfd;
	//不显示显示客户端的IP
	int n_acpt(int fd){
    int cfd = accept(fd,NULL,NULL);
    if(cfd == -1){
        printf("%s\n",strerror(errno));
    }
    return cfd;
}

//显示客户端的IP地址
int h_acpt(int fd){
    SA4 cli;
    char ip[32];
    socklen_t len = sizeof(cli);
    int cfd = accept(fd,(SA*)&cli,&len);
    if(cfd == -1){
        printf("%s\n",strerror(errno));
        return -1;
    }
    printf("%s\n",inet_ntop(AF_INET,&cli.sin_addr,ip,32));
    return cfd;
}

编写完源文件,也可把源文件封装成动态库
具体步骤如下:
1)生成与文件无关的可执行文件

gcc - c -fPIC t_net.c
2)打包动态库
gcc -shared -o libt_net.so t_net.o
3)将动态库移动到/lib目录下.
在编译的时候加上-lt_net即可
2 服务器的数据处理

#include <unistd.h>
#include <ctype.h>
#include <string.h>
int t_main(int cfd){
    //读取客户端的请求消息,read阻塞
    char buf[128];
    while(1){
        int r = read(cfd,buf,128);
        for(int i = 0;i < r ;i++)
            buf[i] = toupper(buf[i]);
        write(cfd,buf,r);
        if(strcmp(buf,"BYEBYE") == 0) break;
    }   
    return 0;
}

服务器的数据处理部分很简单,就是使用read函数读取客户段中的数据.并将服务端中的数据写回给客户端
3) 并发部分的实现
当一个客户端与服务器建立连接之后,在断开连接之前.服务器无法从未决连接队列中与其他的客户端建立连接.因此,需要一定手段来实现并发.
有三种方式:多线程 多进程 多路复用 epoll
这里使用的是多进程

父进程的任务
① 负责从未决连接队列中取出一个进行连接处理,返回一个连接描述符.
②创建子进程,子进程继承父进程的文件描述符.
③ 关闭连接描述符.
④负责回收子进程的资源.

子进程负责的任务
① 关闭设备描述符
② 使用连接描述符处理客户的业务
③处理完毕,关闭连接描述符
④ exit(0)
相关代码

#include <t_net.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#include <signal.h>

//子进程终止时给父进程发送SIGCHLD信号
void handle(int n){
    //回收子进程的资源
    wait(NULL);
    return ;
}
extern int t_main(int cfd);
int main(void){
    //创建一个socket设备,返回该设备的文件描述符
    signal(SIGCHLD,handle);
    char buffer[128];
    SA4 cli;
    int s_fd = s_listen(AF_INET,SOCK_STREAM,8000,5);
    if(s_fd == -1){
        return -1;
    }
    while(1){
          int cfd = h_acpt(s_fd);
          if(cfd == -1) return -1;
          pid_t pid = fork();
          //父子进程是异步的
          if(pid == -1){
             printf("%s\n",strerror(errno));
             return -1;
          }
          
if(pid == 0){
            close(s_fd);
            t_main(cfd);
            close(cfd);
            exit(0);
          }
          else{
            close(cfd);
            //阻塞等待
            //waitpid(-1,NULL,WNOHANG);
          }
    }
    close(s_fd);
    return 0;
}

这里使用一个信号函数,在子进程终止的时候会发射SIGCHILD信号,通知父进程回收子进程的资源.
3 TCP客户端的编程模型
1)创建socket设备socket(2);
2)绑定IP地址和端口号bind(2);
3)和服务器建立连接
4)循环处理数据 write(2) read(2)
5)关闭本次连接 close(2)
相关代码:

#include <t_net.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>

int main(int argc,char* argv[]){
    //创建套接字
    char msg[128];
    if(argc < 2){
        printf("参数过少\n");
        return 0;
    }
    int cfd = socket(AF_INET,SOCK_STREAM,0);
    if(cfd == -1){
        printf("%s\n",strerror(errno));
        return 0;
    }
	 //向服务器发起请求
    SA4 addr;
    memset(&addr,0,sizeof(addr));
    addr.sin_family = AF_INET;
    //端口号
    addr.sin_port = htons(8000);
    char *ipaddress = argv[1];
    struct in_addr ip;
    inet_pton(AF_INET,ipaddress,&ip);
    addr.sin_addr = ip;
    int ret = connect(cfd,(SA*)&addr,sizeof(SA));
    if(ret == 0){
        printf("连接成功...\n");
    }
    else{
        printf("连接失败...\n");
        return 0;
    }
    while(1){
     gets(msg);
        write(cfd,msg,sizeof(msg));
        char rbuf[128];
        int r = read(cfd,rbuf,sizeof(rbuf));
        printf("message from server:\n");
        printf("%s\n",rbuf);
        if(strcmp(rbuf,"BYEBYE") == 0) break;
    }
    close(cfd);
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TCP并发服务器的编程实现 的相关文章

  • 程序猿眼中的协议:TCP / IP 五层网络模型

    哈喽 大家好 我是你们的老朋友 保护小周 本期为大家带来的是 网络基础原理中的 TCP IP 五层网络模型 主要从协议的概念 网络模型 数据分层传输的流程 几个方面讲解 看完之后可以轻松的理解数据是如何在网络中传输的 确定不来看看嘛 更多精
  • 使用HTTPS模式建立高效爬虫IP服务器详细步骤

    嘿 各位爬虫小伙伴们 想要自己建立一个高效的爬虫IP服务器吗 今天我就来分享一个简单而强大的解决方案 使用HTTPS模式建立工具 本文将为你提供详细的操作步骤和代码示例 让你快速上手 轻松建立自己的爬虫IP服务器 1 准备工作 在开始之前
  • 西门子PLC S7-1200程序实例 西门子1200与安川机器人TCP/IP通讯,包含机器人GSD文件

    西门子PLC S7 1200程序实例 博图版本V15 仅供电气编程者学习借鉴 1 西门子1200与安川机器人TCP IP通讯 包含机器人GSD文件 2 西门子1200控制6轴伺服电机 四台台脉冲控制台达B2伺服 两台PN通讯控制西门子V90
  • L2TP和PPTP的区别

    用最短的时间搞清楚L2TP和PPTP的区别 一 相关知识铺垫 1 虚拟隧道协议 一种通过公共网络的基础设施 在专用网络或专用设备之间实现加密数据通信的技术 通信的内容是可以是任何通信协议的数据包 隧道协议将这些协议的数据包重新封装在新的包中
  • tcp和udp,通信协议

    1 什么是tcp和udp 常用的网络通讯 浏览网页 软件聊天等等 都是基于tcp和udp传输的 2 tcp和udp的区别是什么 1 最大的区别是一个基于连接 一个基于非连接 举例说明 如果把人与人之间的通信比喻为进程之间的通信 写信和电话
  • 【网络自定向下学习】——TCP报文段的详细解析

    个人主页 努力学习的少年 版权 本文由 努力学习的少年 原创 在CSDN首发 需要转载请联系博主 如果文章对你有帮助 欢迎关注 点赞 收藏 一键三连 和订阅专栏哦 目录 一 Tcp报文段的结构 二 首部长度 三 窗口大小 四 序列号和确认序
  • TCP/IP详解 卷1:协议 学习笔记 第十六章 BOOTP:引导程序协议

    一个无盘系统在不知道自身IP地址情况下 进行系统引导时能通过RARP协议获取它的IP地址 使用RARP会有两个问题 1 IP地址是返回的唯一结果 2 RARP使用链路层广播 RARP请求不会被路由器转发 每个实际网络必须设置一个RARP服务
  • 一些优秀的开源轻量级TCP/IP协议栈

    以下是一些优秀的开源轻量级TCP IP协议栈 它们适用于嵌入式设备和其他资源受限的环境 lwIP lightweight IP lwIP 是一个非常流行的开源 TCP IP 协议栈 它专门为嵌入式系统设计 具有低内存占用和高效率的特点 lw
  • Kali如何配置静态IP,并且实现网络访问

    1 本地网络配置 我是使用VMware workstation的桥接网络 配置IP要根据对应的网络模式下对应的网络段进行配置 才能保证Kali与别的主机正常通信 桥接网络模式 我需要先看一下宿主机的网络IP地址 WIN r输入cmd 回车
  • 计算机网络(五)——应用层HTTP协议

    HTTP 文章目录 HTTP 1 HTTP协议是什么 2 HTTP协议格式 2 1请求包含信息 2 2响应包含信息 2 3请求响应格式 2 4模拟发送请求打印响应结果 2 5请求响应头中的Content 2 6模拟响应服务器 3 HTTP优
  • TCP/IP协议栈及网络基础,协议栈原理及实现

    1 TCP IP协议栈及网络基础 推荐这个在B站几千观看的视频讲解 底层原理到徒手实现 TCP IP网络协议栈 tcp协议栈 如何实现 C C Linux服务器开发高级架构学习视频点击 C C Linux服务器开发高级架构师 Linux后台
  • 如何批量Ping 1000个IP地址,一个小技巧节约N小时?

    一 批量ping网段 对于一个网段ip地址众多 如果单个检测实在麻烦 那么我们可以直接批量ping网段检测 那个ip地址出了问题 一目了然 先看代码 直接在命令行窗口输入 for L D in 1 1 255 do ping 10 168
  • OSI七层模型和TCP/IP五层模型

    一 OSI七层模型 七层模型从下往上依次为物理层 数据链路层 网络层 传输层 会话层 表示层 应用层 各层功能如图所示 应用层 与其它计算机进行通讯的一个应用 它是对应应用程序的通信服务的 例如 一个没有通信功能的自处理程序就不能执行通信的
  • OSI七层模型以及各层的作用

    OSI七层模型 OSI七层模型包括 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 具体作用 物理层 主要定义物理设备标准 如网线的接口类型 各种传输介质的传输速率等 主要作用是传输bit流 主要设备 集线器 数据链路层 主要将
  • 在外远程登录局域网下的象过河ERP管理系统,无需公网IP

    文章目录 概述 1 查看象过河服务端端口 2 内网穿透 3 异地公网连接 4 固定公网地址 4 1 保留一个固定TCP地址 4 2 配置固定TCP地址 5 使用固定地址连接 转发自CSDN远程穿透的文章 公网远程访问公司内网象过河ERP系统
  • IP网址可访问,域名网址无法访问

    可以通过修改DNS排查问题 一 修改DNS的好处 适当提高上网速度 更换DNS可以访问某些因为域名解析存在问题而不能访问的网站 可以屏蔽运营商的广告 还可以帮助您避免被钓鱼的危险 二 修改DNS带来的副作用 无法访问页面或者访问的页面不是你
  • time_wait的快速回收和重用

    问题现象 PC与工控机之间通信 工控机发送SYN PC一直回复FIN或者RST 问题解释 1 time wait产生的原因及作用 下面我们先来简单回顾一下TCP连接关闭动作 在Linux环境下我们可以如下的方式来统计TCP连接的情况 net
  • 前阿里P6花七天时间整理地方软件测试基础知识,高手请绕道

    可以说软件测试所学习的知识都是在循序渐进的 从更基础的知识逐渐延伸到困难的知识 由此可以看出 基础知识是这些重难点知识延伸的基础 想要升职加薪 基础知识必须牢靠 一 软件测试概述 1 软件缺陷 软件缺陷 又称之为 Bug 即计算机软件或程序
  • 分辨公网IP和内网IP的方法

    公网IP一般就是对外的访问地址 内网IP就是对内的访问地址 两者的使用范围是不一样的 那如果区分客户网络的IP地址是公网IP地址还是内网IP地址呢 公网IP的地址范围是很广泛的 我们可以先了解下内网IP 因为内网IP的地址段相对是局限的 一
  • 如何使用Imagewheel搭建一个简单的的私人图床无公网ip也能访问

    文章目录 1 前言 2 Imagewheel网站搭建 2 1 Imagewheel下载和安装 2 2 Imagewheel网页测试 2 3 cpolar的安装和注册 3 本地网页发布 3 1 Cpolar临时数据隧道

随机推荐

  • 2021年11月世界编程语言排行

    2021年11月世界编程语言排行 11 月头条 PHP 即将失去前 10 名的位置 自 TIOBE 指数启动以来 20 多年前 PHP 一直是排名前 10 的永久玩家 最近 我们看到 PHP 努力保持在前 10 名 PHP 曾经是 Web
  • 腾讯云轻量服务器安装宝塔镜像使用入门教程(初体验)

    腾讯云轻量应用服务器30M峰值带宽24元 月 价格很不错新手站长网选择了一台入门级1核1G的轻量应用服务器lighthouse 镜像安装宝塔Linux面板 新手站长网来详细说下腾讯云香港轻量应用服务器从购买选择到建站入门教程 腾讯云香港轻量
  • JS各种校验规则

    目录 1 校验是否为整数 2 验证开始时间是否大于结束时间 3 校验手机号是否正确 4 校验身份证是否合法 5 校验字符串是否为正整数 6 去除两端空白判断是否为空 7 校验邮箱是否合理 1 校验是否为整数 var flowNum flow
  • 微信支付服务器端代码,APP接入微信支付(后台代码)

    配置参数 private config array appid gt 微信开放平台上的应用id mch id gt 微信申请成功之后邮件中的商户id api key gt 在微信商户平台上自己设定的api密钥 32位 notify url
  • 祖传Python代码,初学者必用,含泪发出

    今天分享几段工作生活中常用的代码 都是最为基础的功能和操作 而且大多还都是出现频率比较高的 很多都是可以拿来直接 使用或者简单修改就可以放到自己的项目当中 日期生成 很多时候我们需要批量生成日期 方法有很多 这里分享两段代码 Python学
  • 华为HJ2 计算某字符出现次数

    a input b input num 0 for i in range len a if b lower a i lower num num 1 print num
  • CUDA基本优化方法

    一 基于编程模型和执行模型的优化方法 1 选取合适的gridDim和blockDim blockDim最好为32的整数倍 因为执行指令的基本单位为线程束 线程束内的所有线程统一执行广播下来的命令 而线程束的线程数量基本为32 当block被
  • xx排排网数据加密(js逆向)

    网址 aHR0cHM6Ly9kYy5zaW11d2FuZy5jb20v 点翻页看抓包信息 这个data就是加密后的数据 这里的key是一段代码 这是解密所需的key 先拿出来格式化看看 这个和加速乐的处理方法是一样的 把evel换成cons
  • 【Pygame经典合集】​​​​​​终极白给大招:让你玩儿到爽(附多款游戏源码)

    导语 嘿 我是木木子 关注我 跟我一起玩游戏啦 其实嘛 最近的话游戏的话实在是没什么可以写的了 很多游戏的话太难仿制起来很费时间 于是 就有了今天这篇小合集 哈哈哈 这是一个pygame的项目 内含4款单个游戏的哦 想玩那款玩儿那款的哈 今
  • RS485通讯接口定义图详解

    RS485采用差分信号负逻辑 2V 6V表示 0 6V 2V表示 1 RS485有两线制和四线制两种接线 四线制只能实现点对点的通信方式 现很少采用 现在多采用的是两线制接线方式 这种接线方式为总线式拓朴结构在同一总线上最多可以挂接32个结
  • docked --debug 功能

    docker不正常时使用查看 太好用了 bip Bridge IP 是Docker的配置选项之一 用于指定Docker守护进程创建的网络桥接接口的IP地址和子网掩码 在设置bip时 确保所指定的IP地址不以0结尾 当使用以0结尾的IP地址作
  • 移动app自动化测试工具发展历程--完整版

    最近在总结关于移动app的自动化测试的系列文章 本来想在7月份推出这个系列 但是又担心7月份的天气太热 开空调费油 所以索性 想到哪就整理到哪 持续的推出来吧 今天先把移动app自动化测试工具总结一下 我大概的搜索了一下 本站的大佬 整理的
  • (C语言)矩阵转置 (10分)

    将一个3 3矩阵转置 即行和列互换 输入格式 在一行中输入9个小于100的整数 其间各以一个空格间隔 输出格式 输出3行3列的二维数组 每个数据输出占4列 输入样例 1 2 3 4 5 6 7 8 9 输出样例 1 4 7 2 5 8 3
  • 自己造一个简易的IOC轮子

    简易的IOC流程编写笔记 首先先对这个小demo做一个说明 首先这个demo是很简易的 里面有一些可以优化的复杂点我设置了TODO 如果你有兴趣的话 可以自己去完善一下 写这个demo就是为了让自己对IOC的一个流程更加熟悉 对于刚开始学习
  • 【ROS工具】ROS基础学习

    ROS基础学习 1 基本介绍 2 实际操作 1 基本介绍 ROS Robot Operating System 是一个机器人操作系统 开始于2007 三个中长期支持版本 对应着Ubuntu的三个LTS版本如下 ROS术语 主节点 ros m
  • 1139 First Contact(unique函数,string.substr()函数)

    PTA 程序设计类实验辅助教学平台 用map套个set来实现邻接表 排序都免了 include
  • Android开发之Retrofit/OkHttp使用

    OkHttp 简介 OkHttp是时下最火的Http请求框架 其官网及源码地址如下 OkHttp官网地址 http square github io okhttp OkHttp源码地址 https github com square okh
  • .Net下正则匹配规则

    Net中常用的正则表达式选项 1 IgnoreCase 忽略大小写 匹配时不区分大小写 2 Multiline 多行模式 更改 和 的含义 使它们分别在任意一行的行首和行尾匹配 而不仅仅在整个字符串的开头和结尾匹配 在此模式下 的精确含意是
  • 寻找小数

    题目描述 有一个分数a b 你需要找到数字c在这个数的小数点后第一次出现的位置 输入格式 输入一行 包含三个整数a b c 输出格式 输出一个整数 如果不存在c 输出 1 样例输入 1 2 0 样例输出 2 约定 1 lt a
  • TCP并发服务器的编程实现

    TCP并发服务器的编程实现 1 基于TCP的服务器编程模型 创建通信端点 套接字 返回该端点的文件描述符 sfd socket 2 2 将sfd和本地的ip地址和端口号绑定 bind 2 3 将sfd设置为被动连接状态 监听客户端的到来 如