l8-d8 TCP并发实现

一、TCP多进程并发

1.地址快速重用

先退出服务端,后退出客户端,则服务端会出现以下错误:

地址仍在使用中

解决方法:

/*地址快速重用*/
    int flag=1,len= sizeof (int);
    if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len) == -1) {
              perror("setsockopt");
              exit(1);
    }

 2.多进程并发

1)fork函数

#include <stdio.h>
#include <wait.h>
#include <stdlib.h>int main(int argc, char *argv[])
{pid_t pid = fork();if(pid < 0){perror("fork");exit(0);}else if(pid == 0){printf("This is child process.\n");}else{printf("This is father process.\n");wait(NULL);}return 0;
}

2)多个客户端

代码演示

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>#define BACKLOG 5
void ClinetHandle(int newfd);
int main(int argc, char *argv[])
{int fd, newfd;struct sockaddr_in addr, clint_addr;socklen_t addrlen = sizeof(clint_addr);pid_t pid;if(argc < 3){fprintf(stderr, "%s<addr><port>\n", argv[0]);exit(0);}/*创建套接字*/fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if ( inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*地址快速重用*/int flag=1,len= sizeof (int); if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len) == -1) { perror("setsockopt"); exit(1); } /*绑定通信结构体*/if(bind(fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1){perror("bind");exit(0);}/*设置套接字为监听模式*/if(listen(fd, BACKLOG) == -1){perror("listen");exit(0);}while(1){/*接受客户端的连接请求,生成新的用于和客户端通信的套接字*/newfd = accept(fd, (struct sockaddr *)&clint_addr, &addrlen);if(newfd < 0){perror("accept");exit(0);}printf("addr:%s port:%d\n", inet_ntoa(clint_addr.sin_addr), ntohs(clint_addr.sin_port) );if( (pid = fork() ) < 0){perror("fork");exit(0);}else if(pid == 0){close(fd);ClinetHandle(newfd);exit(0);}elseclose(newfd);}close(fd);return 0;
}
void ClinetHandle(int newfd){int ret;char buf[BUFSIZ] = {};while(1){//memset(buf, 0, BUFSIZ);bzero(buf, BUFSIZ);        //初始化ret = read(newfd, buf, BUFSIZ);if(ret < 0){perror("read");exit(0);}else if(ret == 0)break;elseprintf("buf = %s\n", buf);}close(newfd);
}

二、僵尸进程处理

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <sys/wait.h>#define BACKLOG 5
void SigHandle(int sig){if(sig == SIGCHLD){printf("client exited\n");wait(NULL);}
}
void ClinetHandle(int newfd);
int main(int argc, char *argv[])
{int fd, newfd;struct sockaddr_in addr, clint_addr;socklen_t addrlen = sizeof(clint_addr);#if 0struct sigaction act;act.sa_handler = SigHandle;act.sa_flags = SA_RESTART;sigemptyset(&act.sa_mask);sigaction(SIGCHLD, &act, NULL);
#elsesignal(SIGCHLD, SigHandle);
#endifpid_t pid;if(argc < 3){fprintf(stderr, "%s<addr><port>\n", argv[0]);exit(0);}/*创建套接字*/fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if ( inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*地址快速重用*/int flag=1,len= sizeof (int); if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len) == -1) { perror("setsockopt"); exit(1); } /*绑定通信结构体*/if(bind(fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1){perror("bind");exit(0);}/*设置套接字为监听模式*/if(listen(fd, BACKLOG) == -1){perror("listen");exit(0);}while(1){/*接受客户端的连接请求,生成新的用于和客户端通信的套接字*/newfd = accept(fd, (struct sockaddr *)&clint_addr, &addrlen);if(newfd < 0){perror("accept");exit(0);}printf("addr:%s port:%d\n", inet_ntoa(clint_addr.sin_addr), ntohs(clint_addr.sin_port) );if( (pid = fork() ) < 0){perror("fork");exit(0);}else if(pid == 0){close(fd);ClinetHandle(newfd);exit(0);}elseclose(newfd);}close(fd);return 0;
}
void ClinetHandle(int newfd){int ret;char buf[BUFSIZ] = {};while(1){//memset(buf, 0, BUFSIZ);bzero(buf, BUFSIZ);ret = read(newfd, buf, BUFSIZ);if(ret < 0){perror("read");exit(0);}else if(ret == 0)break;elseprintf("buf = %s\n", buf);}close(newfd);
}

三、TCP并发多线程

 

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <pthread.h>#define BACKLOG 5void *ClinetHandle(void *arg);
int main(int argc, char *argv[])
{int fd, newfd;struct sockaddr_in addr, clint_addr;pthread_t tid;socklen_t addrlen = sizeof(clint_addr);if(argc < 3){fprintf(stderr, "%s<addr><port>\n", argv[0]);exit(0);}/*创建套接字*/fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if ( inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*地址快速重用*/int flag=1,len= sizeof (int); if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, len) == -1) { perror("setsockopt"); exit(1); } /*绑定通信结构体*/if(bind(fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1){perror("bind");exit(0);}/*设置套接字为监听模式*/if(listen(fd, BACKLOG) == -1){perror("listen");exit(0);}while(1){/*接受客户端的连接请求,生成新的用于和客户端通信的套接字*/newfd = accept(fd, (struct sockaddr *)&clint_addr, &addrlen);if(newfd < 0){perror("accept");exit(0);}printf("addr:%s port:%d\n", inet_ntoa(clint_addr.sin_addr), ntohs(clint_addr.sin_port) );pthread_create(&tid, NULL, ClinetHandle, &newfd);    //创建线程pthread_detach(tid);    //设置为分离属性}close(fd);return 0;
}
void *ClinetHandle(void *arg){int ret;char buf[BUFSIZ] = {};int newfd = *(int *)arg;    //传参,强转while(1){//memset(buf, 0, BUFSIZ);bzero(buf, BUFSIZ);ret = read(newfd, buf, BUFSIZ);if(ret < 0){perror("read");exit(0);}else if(ret == 0)break;elseprintf("buf = %s\n", buf);}printf("client exited\n");close(newfd);return NULL;
}

Makefile


CC=gcc
CFLAGS=-Wall
all:client server

server:server.c
    $(CC) $^ -Wall -o $@ -lpthread

clean:
    rm client server
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/124672.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

yum安装mysql5.7散记

## 数据源安装 $ yum -y install wget $ wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm $ yum localinstall mysql57-community-release-el7-8.noarch.rpm $ yum repolist enabled | grep "mysql.*-community.*" $ yum install mysql-…

宇凡微YE09合封芯片,集成高性能32位mcu和2.4G芯片

合封芯片是指将主控芯片和外部器件合并封装的芯片&#xff0c;能大幅降低开发成本、采购成本、减少pcb面积等等。宇凡微YE09合封芯片&#xff0c;将技术领域推向新的高度。这款高度创新性的芯片融合了32位MCU和2.4G芯片&#xff0c;为各种应用场景提供卓越的功能和性能。 32位M…

谈一谈冷门的C语言爬虫

目录 C语言写爬虫是可行的 C语言爬虫不受待见 C语言爬虫有哪些可用的库和工具 C语言爬虫示例 总结 在当今的编程世界中&#xff0c;C语言相比于一些主流编程语言如Python、JavaScript等&#xff0c;使用范围相对较窄。然而&#xff0c;尽管C语言在爬虫领域的应用并不常见&…

Redis持久化、主从与哨兵架构详解

Redis持久化 RDB快照&#xff08;snapshot&#xff09; 在默认情况下&#xff0c; Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。 你可以对 Redis 进行设置&#xff0c; 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时&#xff0c; 自动保存一次数…

MIT6.824 Spring2021 Lab 1: MapReduce

文章目录 0x00 准备0x01 MapReduce简介0x02 RPC0x03 调试0x04 代码coordinator.gorpc.goworker.go 0x00 准备 阅读MapReduce论文配置GO环境 因为之前没用过GO,所以 先在网上学了一下语法A Tour of Go 感觉Go的接口和方法的语法和C挺不一样, 并发编程也挺有意思 0x01 MapRed…

OCR多语言识别模型构建资料收集

OCR多语言识别模型构建 构建多语言识别模型方案 合合&#xff0c;百度&#xff0c;腾讯&#xff0c;阿里这四家的不错 调研多家&#xff0c;发现有两种方案&#xff0c;但是大多数厂商都是将多语言放在一个字典里&#xff0c;构建1w~2W的字典&#xff0c;训练一个可识别多种语…

解决报错之org.aspectj.lang不存在

一、IDEA在使用时&#xff0c;可能会遇到maven依赖包明明存在&#xff0c;但是build或者启动时&#xff0c;报找不存在。 解决办法&#xff1a;第一时间检查Setting->Maven-Runner红圈中的√有没有选上。 二、有时候&#xff0c;明明依赖包存在&#xff0c;但是Maven页签中…

监听Helm release资源

监听Helm release资源 基于helm做部署管理工具时&#xff0c;可能想要管理用户已有环境&#xff0c;这时需要将已有环境中的release信息上报到业务系统中。当用户在环境中部署新的release时&#xff0c;也需要实时监听并上报回来。下面将讲解如何去监听release资源 helm rele…

湖南省副省长秦国文一行调研考察亚信科技

9月5日&#xff0c;湖南省人民政府党组成员、副省长秦国文一行到亚信科技调研考察&#xff0c;亚信科技高级副总裁陈武主持接待。 图&#xff1a;双方合影 在亚信科技创新展示中心&#xff0c;秦国文了解了亚信科技在5G、算力网络、人工智能、大数据等前沿领域的创新探索&…

Git 基本原理和常用操作

Git Git 是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。由 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开源的版本控制软件。 Git 常用操作 git 提交流程&#xff1a;工作区 -> git add 到暂存区 -> gi…

Pytorch中如何加载数据、Tensorboard、Transforms的使用

一、Pytorch中如何加载数据 在Pytorch中涉及到如何读取数据&#xff0c;主要是两个类一个类是Dataset、Dataloader Dataset 提供一种方式获取数据&#xff0c;及其对应的label。主要包含以下两个功能&#xff1a; 如何获取每一个数据以及label 告诉我们总共有多少的数据 Datal…

C++多态【下】

文章目录 1.多态实现的底层1.1初识多态原理1.2深入理解虚函数表1.单继承虚函数表2.探究虚函数表存储数据3.知识点金4.多继承虚函数表 2.题目讲解 1.多态实现的底层 1.1初识多态原理 class Dad { public:virtual void Cook() { cout << "佛跳墙" << en…

Can‘t connect to local MySQL server through socket ‘/tmp/mysql.sock‘

最近在用django框架开发后端时&#xff0c;在运行 $python manage.py makemigrations 命令时&#xff0c;报了以上错误&#xff0c;错误显示连接mysql数据库失败&#xff0c;查看了mysql数据库初始化配置文件my.cnf&#xff0c;我的mysql.sock文件存放路径配置在了/usr/local…

【微服务部署】08-监控与告警

文章目录 1. PrometheusOperator1.1 优势1.2 配置脚本1.3 部署脚本 2. Granfana实现监控看板2.1 Granfana核心特性2.2 部署文件 3. prometheus-net收集自定义指标3.1 组件包3.2 使用场景 目前Kubernetes中最流行的监控解决方案是使用Prometheus和AlertManager 1. PrometheusOpe…

jar包或exe程序设置为windows服务

最近在使用java和python制作客户端时突发奇想&#xff0c;是否能够通过一种方法来讲jar包和exe程序打包成windows服务呢&#xff1f;简单了解了一下是可以的。 首先要用到的是winSW&#xff0c;制作windows服务的过程非常简单&#xff0c;仅需几步制作完成&#xff0c;也不需要…

ESP32-C3的存储器类型

本文主要参考ESP-IDF编程指南&#xff0c;一点小记录。 ESP32-C3的存储器有&#xff1a; ESP-IDF 区分了指令总线&#xff08;IRAM、IROM、RTC FAST memory&#xff09;和数据总线 (DRAM、DROM)。 内部SRAM的一部分是指令RAM(IRAM)。那为什么要把指令放在RAM中&#xff0c;就是…

Zookeeper简述

数新网络-让每个人享受数据的价值 官网现已全新升级—欢迎访问&#xff01; 前 言 ZooKeeper是一个开源的、高可用的、分布式的协调服务&#xff0c;由Apache软件基金会维护。它旨在帮助管理和协调分布式系统和应用程序&#xff0c;提供了一个可靠的平台&#xff0c;用于处理…

QT第二天

1.优化登陆界面&#xff0c;当点击登录按钮后&#xff0c;在该按钮对应的槽函数中&#xff0c;判断账户和密码框内的数据是否为admin和123456&#xff0c;如果账户密码匹配成功&#xff0c;则提示登陆成功并关闭登录界面&#xff0c;如果账户密码匹配失败&#xff0c;则提示登录…

嵌入式开发-11 Linux下GDB调试工具

目录 1 GDB简介 2 GDB基本命令 3 GDB调试程序 1 GDB简介 GDB是GNU开源组织发布的一个强大的Linux下的程序调试工具。 一般来说&#xff0c;GDB主要帮助你完成下面四个方面的功能&#xff1a; 1、启动你的程序&#xff0c;可以按照你的自定义的要求随心所欲的运行程序&#…

介绍PHP

PHP是一种流行的服务器端编程语言&#xff0c;用于开发Web应用程序。它是一种开源的编程语言&#xff0c;具有易学易用的语法和强大的功能。PHP支持在服务器上运行的动态网页和Web应用程序的快速开发。 PHP可以与HTML标记语言结合使用&#xff0c;从而能够生成动态的Web页面&a…