网络编程(8.14)TCP并发服务器模型
作业:
1. 多线程中的newfd,能否修改成全局,不行,为什么?
2. 多线程中分支线程的newfd能否不另存,直接用指针间接访问主线程中的newfd,不行,为什么?
多线程并发服务器模型原代码:
#include<stdio.h>
#include<head.h>
#include<netinet/in.h>
#define PROT 1112
#define IP "192.168.125.133"
void handler(int sig)
{while(waitpid(-1,NULL,WNOHANG)>0);
}
struct climsg
{int nfd;struct sockaddr_in cin;};
void* deal_cli_msg(void *arg);
int main(int argc, const char *argv[])
{//捕获17信号if(signal(17,handler)==SIG_ERR){ ERR_MSG("signal");return -1; } //创建流式套接字int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd<0){ ERR_MSG("socket");return -1; } printf("sfd=%d\n",sfd);//设置允许端口被快速复用int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0){ ERR_MSG("setsockopt");return -1; } printf("允许端口快速复用成功\n");//绑定服务器的IP和端口--->必须绑定struct sockaddr_in sin;sin.sin_family = AF_INET;//必须填AF_INETsin.sin_port = htons(PROT);//端口号:1024~49151sin.sin_addr.s_addr = inet_addr(IP);//本机IPif(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0){ ERR_MSG("bind");return -1; } printf("绑定成功\n");//将套接字设置为被动监听状态if(listen(sfd,128)<0){ ERR_MSG("listen");return -1; } printf("被动监听状态设置成功\n");//从已完成连接的队列中获取一个客户端信息,生成一个新的文件描述符struct sockaddr_in cin;//存储客户端地址信息socklen_t addrlen = sizeof(cin);pthread_t tid;int nfd=-1;struct climsg info;while(1){ nfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);if(nfd<0){ERR_MSG("accept");return -1; }printf("[%s:%d]nfd=%d,客户端连接成功\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),nfd);info.nfd=nfd;info.cin=cin;//该文件描述符才是客户端通信的文件描述符if(pthread_create(&tid,NULL,deal_cli_msg,(void *)&info)!=0){printf("pthread_create failed __%d__\n",__LINE__);return -1; }} close(sfd);return 0;
}
void* deal_cli_msg(void *arg)
{char buf[128]="";ssize_t res=0;int nfd =((struct climsg*) arg)->nfd;struct sockaddr_in cin =((struct climsg*) arg)->cin;while(1){ bzero(buf,sizeof(buf));//接受数据res=recv(nfd,buf,sizeof(buf),0);if(res<0){ERR_MSG("recv");break;}else if(0==res){printf("[%s:%d]nfd=%d 客户端下线\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),nfd);break;}printf("nfd=%d : %s\n",nfd,buf);//发送数据strcat(buf,"*_*");if(send(nfd,buf,sizeof(buf),0)<0){ERR_MSG("send");break;}printf("发送成功\n");}close(nfd);return 0;
}
1.将newfd改成全局变量效果:

答:不行,因为newfd是全局变量的话,客户端连接后生成的新的文件描述符会一直覆盖上一次保存的文件描述符,导致客户端下线时只能关闭最新创建的文件描述符,无法关闭之前客户端连接时创建的文件描述符。
2.不保存分支线程的newfd,直接用指针间接访问主线程中的newfd效果:

与第一题效果相同,不保存nfd时有客户端创建连接会一直覆盖结构体里的文件描述符nfd的数据,导致断开连接时关闭的文件描述符nfd取的是结构体里最新的 ,导致之前创建连接时开启的文件描述符没有被保存导致无法关闭。
3.基于UDP的TFTP文件传输
TFTP通信过程总结
- 服务器在69号端口等待客户端的请求
- 服务器若批准此请求,则使用 临时端口 与客户端进行通信。
- 每个数据包的编号都有变化(从1开始)
- 每个数据包都要得到ACK的确认,如果出现超时,则需要重新发送最后的数据包或ACK包
- 数据长度以512Byte传输的,小于512Byte的数据意味着数据传输结束。


下载代码:
#include<stdio.h>
#include<head.h>
#define PORT 69
int main(int argc, const char *argv[])
{char IP[128]="";printf("请输入IP:\n");scanf("%s",IP);char name[128]="";printf("请输入文件名:\n");scanf("%s",name);//创建报式套接字int sfd=socket(AF_INET,SOCK_DGRAM,0);if(sfd<0){ ERR_MSG("socket");return -1; } printf("sfd=%d\n",sfd);//填充客户端自身的地址信息结构体,真实的地址信息结构体根据地址族指定//AF_INET : man 7 ip; struct sockaddr_in sin;sin.sin_family = AF_INET;//必须填AF_INETsin.sin_port = htons(PORT);//服务器端口号:1024~49151sin.sin_addr.s_addr = inet_addr(IP);//服务器IP ifconfig查看ssize_t res=0;struct sockaddr_in rcvaddr;socklen_t addrlen = sizeof(rcvaddr);char data[516]="";//数据包char ACK[4]="";//ACK包size_t i=4;char *p=data;short *p1=(short*)data;*p1=htons(1);char *p2=data+2;strcpy(p2,name);char *p3=p2+strlen(p2)+1;strcpy(p3,"octet");//发送读写请求if(sendto(sfd,p,(i+strlen(p2)+strlen(p3)),0,(struct sockaddr*)&sin,sizeof(sin))<0){ ERR_MSG("sendto");return -1; } bzero(data,sizeof(data));int fp=open(name,O_WRONLY|O_CREAT|O_TRUNC,0664);while(1){ //接收数据res=recvfrom(sfd,data,sizeof(data),0,(struct sockaddr*)&rcvaddr,&addrlen);if(res<0){ ERR_MSG("recvfrom");return -1; } if(write(fp,data+4,res-4)<0){ ERR_MSG("write");close(fp);return -1; } if(res<516){ printf("传输完毕\n");break;}//发送数据short *m1=(short *)ACK;*m1=htons(4);short *m2=m1+1;*m2=*((short *)data+1);if(sendto(sfd,ACK,i,0,(struct sockaddr*)&rcvaddr,sizeof(rcvaddr))<0){ERR_MSG("sendto");return -1; }bzero(data,sizeof(data));bzero(ACK,sizeof(ACK));} //关闭文件描述符close(sfd);close(fp);return 0;
}
上传代码:
相关文章:
网络编程(8.14)TCP并发服务器模型
作业: 1. 多线程中的newfd,能否修改成全局,不行,为什么? 2. 多线程中分支线程的newfd能否不另存,直接用指针间接访问主线程中的newfd,不行,为什么? 多线程并发服务器模型原代码&…...
认识负载均衡||WEBSHELL
目录 一、负载均衡 1.nginx负载均衡算法 2.nginx反向代理-负载均衡 二、webshell 1.构造不含数字和字母的webshell 2.如何绕过 一、负载均衡 1.nginx负载均衡算法 (1)轮询(默认)每个请求按时间顺序逐一分配到不同的后端服务&…...
Chapter 15: Object-Oriented Programming | Python for Everybody 讲义笔记_En
文章目录 Python for Everybody课程简介Object-oriented programmingManaging larger programsGetting startedUsing objectsStarting with programsSubdividing a problemOur first Python objectClasses as typesObject lifecycleMultiple instancesInheritanceSummaryGlossa…...
模板编程-成员特化
成员特化:类模板特化除了可以对整个类进行特化外,可以只针对某部分成员函数进行特化 全类特化和成员特化都属于全局特化 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring>template<typename T> class CMath { public:CMath(const…...
信安通用基础知识
文章目录 密码学经典误区PGP优良保密协议信安经典其它安全手段XSS与CSRF cross site request forgeryCSRF的利用逻辑CSRF示例CSRF防范检查Referer字段添加校验token XSS cross site scripting common weakness enumeration常见密码api误用(摘自毕设参考文献…...
网上购物系统的设计与实现/在线商城/基于spring boot的电商平台/基于Java的商品销售系统
摘 要 本毕业设计的内容是设计并且实现一个基于Springboot的网上购物系统。它是在Windows下,以MYSQL为数据库开发平台,Tomcat网络信息服务作为应用服务器。网上购物系统的功能已基本实现,主要包括用户管理、数码分类管理、数码产品管理、服…...
uniapp项目-配置store文件夹
1.创建store.js 说明:创建一个新的 Vuex Store 实例,配置 Store 中的模块。 import Vue from vue; import Vuex from vuex; // 导入两个 Vuex 模块:moduleCart 和 moduleUser import moduleCart from /store/cart.js; import moduleUser fr…...
element表格多选实现
表格实现多选 实现表格多选很简单,只需要在表格里加上一列即可,加完之后就会在表格里出现一列白色的四方块按钮,可以多选,也可以单选 <el-table-columntype"selection"width"55"align"center"&…...
宠物智能自动喂食器方案设计
据相关数据表明,2019年全国城镇宠物犬猫数量达到9915万只,增幅达到8.4%,消费市场规模达2024亿元,比2018年增长18.5%,整体呈现持续大幅增长的态势。而养宠人群的主力,为25岁至38岁年轻人,都市白领…...
学习笔记230818---对于promise失败状态处理的重要性
问题描述: 在项目中经常会出现如上的问题,这是因为,用promise封装的接口或第三方组件方法,如果只对成功的状态做处理,就会造成页面出错,报error。 解决方法 then()的末尾加上.catch(()>{})对失败的状态…...
【Redis】什么是缓存击穿,如何预防缓存击穿?
【Redis】什么是缓存击穿,如何预防缓存击穿? 缓存击穿是指一个 Key 非常热点,大并发集中对这一个点进行访问,当这个Key 在失效的瞬间,持续的大并发就会穿破缓存,直接请求数据库。缓存击穿和缓存雪崩的区别…...
Android 13.0 强制app横屏显示
1.概述 在13.0产品定制化开发中,对于处理屏幕旋转方向,首先有kernel底层处理,从底层驱动gsensor 中获取数据,从而判断屏幕方向的,然后事件上报后 最后由WMS就是WindowManagerService 来处理旋转的相关事件 2.强制app横屏显示的核心类 /framework/base/services/java/com…...
平方数之和(力扣)双指针 JAVA
给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a^2 b^2 c 。 示例 1: 输入:c 5 输出:true 解释:1 * 1 2 * 2 5 示例 2: 输入:c 3 输出&am…...
深入浅出Pytorch函数——torch.nn.init.sparse_
分类目录:《深入浅出Pytorch函数》总目录 相关文章: 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...
OpenCV实现BGR2BayerGB/BG格式的转换
1、说明 OpenCV没有提供从BGR生成Bayer格式的接口,需要自己写 OpenCV定义为4种格式,分别为: BGGR排列 -> RG格式 RGGB排列 -> BG格式 GRBG排列 -> GB格式 GBRG排列 -> GR格式 2、转换 void CUtils::BGR2BayerGB(const cv::Mat &matSrc, cv::Mat &matDst)…...
Gateway网关路由以及predicates用法(项目中使用场景)
1.Gatewaynacos整合微服务 服务注册在nacos上,通过Gateway路由网关配置统一路由访问 这里主要通过yml方式说明: route: config: #type:database nacos yml data-type: yml group: DEFAULT_GROUP data-id: jeecg-gateway-router 配置路由:…...
深入浅出Pytorch函数——torch.nn.init.constant_
分类目录:《深入浅出Pytorch函数》总目录 相关文章: 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...
centos mysql8解决Access denied for user ‘root‘@‘localhost‘ (using password: YES)
环境 系统:CentOS Stream release 9 mysql版本:mysql Ver 8.0.34 for Linux on x86_64 问题 mysql登录提示 Access denied for user rootlocalhost (using password: YES)解决方法 编辑 /etc/my.cnf ,在[mysqld] 部分最后添加一行 skip-…...
Docker实战:Docker常用命令
一、镜像相关 1.1、查看镜像 docker images1.2、拉取镜像 docker pull nginx1.3、保存镜像 docker save -o nginx.tar nginx:latest1.4、移除镜像 docker rmi -f nginx:latest1.5、导入镜像 docker load -i nginx.tar二、容器相关 2.1、启动容器 docker run --name red…...
基于51单片机直流电机转速数码管显示控制系统
一、系统方案 本文主要研究了利用MCS-51系列单片机控制PWM信号从而实现对直流电机转速进行控制的方法。本文中采用了三极管组成了PWM信号的驱动系统,并且对PWM信号的原理、产生方法以及如何通过软件编程对PWM信号占空比进行调节,从而控制其输入信号波形等…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
