2024/4/16 网络编程day4

/*TCP并发服务器端*/
#include <myhead.h>
#define SER_IP "192.168.125.173"
#define SER_PORT 8888
void sighanger(int signum){
	if(signum==SIGCHLD){//子进程终止信号
		while(waitpid(-1,NULL,WNOHANG)>0);//循环回收僵尸进程
	}
}

int main(int argc, const char *argv[])
{
	//函数调用出错返回SIG_ERR

	if(signal(SIGCHLD,sighanger)==SIG_ERR){
		perror("signal error");
		return -1;
	}
	//创建套接字
	int rfd=socket(AF_INET,SOCK_STREAM,0);
	if(rfd==-1){
		perror("socket error");
		return -1;
	}
	printf("socket success\n");

	//为服务器绑定ip地址端口号
	struct sockaddr_in cin;
	cin.sin_family=AF_INET;
	cin.sin_port=htons(SER_PORT);
	cin.sin_addr.s_addr=inet_addr(SER_IP);
	if(bind(rfd,(struct sockaddr*)&cin,sizeof(cin))==-1){
			perror("bind error");
			return -1;
			}
	//设置监听
	if(listen(rfd,128)==-1){
		perror("listen error");
		return -1;
	}
	printf("listen success\n");
	struct sockaddr_in sin;
	socklen_t socklen=sizeof(sin);
	while(1){//循环接收客户端请求
		int newfd=accept(rfd,(struct sockaddr*)&sin,&socklen);
		if(newfd==-1){
			perror("accept error");
			return -1;
		}
		pid_t pid=fork();
		if(pid>0){
			close(newfd);
		}else if(pid==0){//子进程数据通信
			close(rfd);
			char rbuf[128]="";
			while(1){
				bzero(rbuf,sizeof(rbuf));
				int res=read(newfd,rbuf,sizeof(rbuf));
				if(res==0){

					printf("客户端已下线\n");
					break;
				}

				printf("[%s:%d]:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),rbuf);
				//将字符串加777发送回去
				strcat(rbuf,"777");
				write(newfd,rbuf,sizeof(rbuf));
				printf("发送成功\n");

			}
			close(newfd);
			exit(EXIT_SUCCESS);
		}
	}
	close(rfd);
	return 0;
}

//多线程实现TCP并发服务器
#include<myhead.h>
#define SER_IP "192.168.125.117"        //服务器IP地址
#define SER_PORT 8888                   //服务器端口号

//定义用于给线程体传参的结构体类型
struct MsgInfo
{
    int newfd;
    struct sockaddr_in cin;
};

//定义线程体函数
void *deal_cli_msg(void *arg)
{

    //将传递进来的数据解析出来
    int newfd = ((struct MsgInfo*)arg)->newfd;
    struct sockaddr_in cin = ((struct MsgInfo*)arg)->cin;

    //5、数据通信
    char rbuf[128] = "";       //用于接受消息
    while(1)
    {
        bzero(rbuf, sizeof(rbuf));    //清空容器
        //从套接字文件中读取消息
        //int ret = read(newfd, rbuf, sizeof(rbuf));
        int ret = recv(newfd, rbuf, sizeof(rbuf), 0);
        if(ret == 0)
        {
            printf("客户端已下线\n");
            break;
        }
        printf("[%s:%d]: %s\n", \
                inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),rbuf );

        //将字符串加个笑脸回回去
        strcat(rbuf, "*_*");
        //write(newfd, rbuf, strlen(rbuf));
        send(newfd, rbuf, strlen(rbuf), 0);
        printf("发送成功\n");

    }

    //6、关闭套接字
    close(newfd);

    //退出线程
    pthread_exit(NULL);


}



/**主程序**/
int main(int argc, const char *argv[])
{
    //1、创建套节字:用于接收客户端链接请求的
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd == -1)
    {
        perror("socket error");
        return -1;
    }
    printf("socket success sfd = %d\n", sfd);     //3

    //设置端口号快速重用
    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1)
    {
        perror("setsockopt error");
        return -1;
    }
    printf("端口号快速重用成功\n");
    
    //2、绑定IP地址和端口号
    //2.1 填充地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;       //地址族
    sin.sin_port = htons(SER_PORT);  //端口号
    sin.sin_addr.s_addr = inet_addr(SER_IP);    //IP地址

    //2.2 绑定工作
    if( bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) ==-1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");


    //3、讲套节字设置成被动监听状态
    if( listen(sfd, 128) == -1)
    {
        perror("listen error");
        return -1;
    }
    printf("listen success\n");

    //4、阻塞等待客户端连接请求
    //定义地址信息结构体变量用于接受客户端的地址信息
    struct sockaddr_in cin;
    socklen_t socklen = sizeof(cin);     //接受地址信息的长度
    
    while(1)
    {
        int newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);
        if(newfd == -1)
        {
            perror("accept error");
            return -1;
        }

        printf("[%s:%d]:已连接, newfd = %d\n",\
                inet_ntoa(cin.sin_addr), ntohs(cin.sin_port) ,newfd);    //4

        //定义用于传参的变量
        struct MsgInfo info = {newfd, cin};
	  //创建分支线程用于通信
        pthread_t tid = -1;
        if(pthread_create(&tid, NULL, deal_cli_msg, &info) != 0)
        {
            printf("线程创建失败\n");
            return -1;
        }
        //回收分支线程的资源
		pthread_detach(tid);

    }

    close(sfd);


    return 0;
}

//流式域套接字服务器端
#include<myhead.h>
int main(int argc, const char *argv[])
{
    //1、创建套节字:用于接收客户端链接请求的
    int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if(sfd == -1)
    {
        perror("socket error");
        return -1;
    }
    printf("socket success sfd = %d\n", sfd);     //3

    //判断要绑定的套接字文件是否存在,如果存在,需要将其删除
    if(access("./unix", F_OK) == 0)
    {
        //说明文件存在,需要将其删除
        if(unlink("./unix") != 0)
        {
            perror("unlink error");
            return -1;
        }
    }

    //2、绑定套接字文件
    //2.1 填充地址信息结构体
    struct sockaddr_un sun;
    sun.sun_family = AF_UNIX;    //通信域
    strcpy(sun.sun_path , "./unix");    //套接字文件


    //2.2 绑定工作
    if( bind(sfd, (struct sockaddr*)&sun, sizeof(sun)) ==-1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");


    //3、讲套节字设置成被动监听状态
    if( listen(sfd, 128) == -1)
    {
        perror("listen error");
        return -1;
    }
    printf("listen success\n");

    //4、阻塞等待客户端连接请求
    //定义地址信息结构体变量用于接受客户端的地址信息
    struct sockaddr_un cun;
    socklen_t socklen = sizeof(cun);     //接受地址信息的长度
    
    int newfd = accept(sfd, (struct sockaddr*)&cun, &socklen);
    if(newfd == -1)
    {
        perror("accept error");
        return -1;
    }

    printf("[%s]:已连接, newfd = %d\n", cun.sun_path,newfd);    //4

    //5、数据通信
    char rbuf[128] = "";       //用于接受消息
    while(1)
    {
        bzero(rbuf, sizeof(rbuf));    //清空容器
        //从套接字文件中读取消息
        //int ret = read(newfd, rbuf, sizeof(rbuf));
        int ret = recv(newfd, rbuf, sizeof(rbuf), 0);
        if(ret == 0)
        {
            printf("客户端已下线\n");
            break;
        }
        printf("[%s]: %s\n", cun.sun_path ,rbuf );

        //将字符串加个笑脸回回去
        strcat(rbuf, "*_*");
        //write(newfd, rbuf, strlen(rbuf));
        send(newfd, rbuf, strlen(rbuf), 0);
        printf("发送成功\n");

    }
    //6、关闭套接字
    close(newfd);
    close(sfd);

    return 0;
}

//报式域套接字服务器端
#include<myhead.h>
int main(int argc, const char *argv[])
{
    //1、创建用于通信的套接字文件描述符
    int sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if(sfd == -1)
    {
        perror("socket error");
        return -1;
    }
    printf("socket success sfd = %d\n", sfd);         //3

    //判断要绑定的套接字文件是否存在,如果存在,需要将其删除
    if(access("./unix", F_OK) == 0)
    {
        //说明文件存在,需要将其删除
        if(unlink("./unix") != 0)
        {
            perror("unlink error");
            return -1;
        }
    }
    //2、绑定IP地址和端口号
    //2.1 填充地址信息结构体
    struct sockaddr_un sun;
    sun.sun_family = AF_UNIX;       //协议族
    strcpy(sun.sun_path, "./unix");   //服务器的套接字文件

    //2.2 绑定工作
    if(bind(sfd, (struct sockaddr*)&sun, sizeof(sun)) == -1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");

    //3、数据的收发
    //定义变量接收客户端地址信息结构体
    struct sockaddr_un cun;
    socklen_t socklen = sizeof(cun);

    char rbuf[128] = "";
    while(1)
    {
        bzero(rbuf, sizeof(rbuf));

        //读取套接字中的数据
        recvfrom(sfd, rbuf, sizeof(rbuf), 0, (struct sockaddr*)&cun, &socklen);
        printf("[%s]:%s\n",cun.sun_path, rbuf);

        //加个笑脸将消息回回去
        strcat(rbuf, "*_*");
        if(sendto(sfd, rbuf, strlen(rbuf), 0, (struct sockaddr*)&cun, sizeof(cun)) ==-1)
        {
            perror("write error");
            return -1;
        }
        printf("发送成功\n");

    }

    //4、关闭套接字
    close(sfd);

    return 0;
}

通过TFTP用UDP实现上传和下载文件

#include <myhead.h>
#define SER_IP "192.168.125.99"
#define SER_PORT 69
#define IP "192.168.125.173"
#define PORT 8888
void download(char data[],short* p1,char* p2){
		char filename[128]="";
		printf("请输入要下载的文件名:");
		fgets(filename,sizeof(filename),stdin);
		filename[strlen(filename)-1]=0;
		int fp=open(filename,O_WRONLY | O_CREAT|O_TRUNC, 0664);//创建文件
		if(fp==-1){
			perror("open error");
			return ;
		}
		*p1=htons(1);//下载
		strcpy(p2,filename);
		char* p4=p2+strlen(filename)+1;
		strcpy(p4,"octet");
		int len=4+strlen(filename)+strlen("octet");
		printf("%s\n",p2);
		int sfd=socket(AF_INET,SOCK_DGRAM,0);
		if(sfd==-1){
			perror("socket error");
			return ;
		}
		struct sockaddr_in rin;
    	rin.sin_family=AF_INET;
		rin.sin_port=htons(PORT);
		rin.sin_addr.s_addr=inet_addr(IP);
		if(bind(sfd,(struct sockaddr*)&rin,sizeof(rin))==-1){
			perror("bind error");
			return ;
		}
		printf("bind success\n");
		struct sockaddr_in sin;
    	sin.sin_family=AF_INET;
		sin.sin_port=htons(SER_PORT);
		sin.sin_addr.s_addr=inet_addr(SER_IP);	
		socklen_t sin_size = sizeof(sin);  
		//发送下载请求
		sendto(sfd,data,len,0,(struct sockaddr*)&sin,sizeof(sin));
		char buf[516];
		short ack[2];
		ack[0]=htons(4);
		int res;
		while(1){
			bzero(buf,sizeof(buf));
			//接收数据到buf
			res=recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, &sin_size);
			//返回接收数据字节数
			//从返回数据包中取出块编号,放到ack中去
			ack[1]=*(short*)(buf+2);
			
			//返回ACK确认
			
			sendto(sfd, ack, sizeof(ack), 0, (struct sockaddr*)&sin, sin_size);
			//将buf中的数据写到文件
			write(fp,buf+4,res-4);//写res-4个数据从buf+4位置到文件
			if(res!=516){
				break;
			}
		}
		close(fp);
}
void transmit(char data[],short* p1,char* p2){
	char filename[128]="";
	printf("请输入要上传的文件名:");
	fgets(filename,sizeof(filename),stdin);
	filename[strlen(filename)-1]=0;
	*p1=htons(2);//写,上传请求
	int fp=open(filename,O_RDONLY, 0664);//打开文件
	strcpy(p2,filename);
	char* p4=p2+strlen(filename)+1;
	strcpy(p4,"octet");
	int len=4+strlen(filename)+strlen("octet");
	int sfd=socket(AF_INET,SOCK_DGRAM,0);
		if(sfd==-1){
			perror("socket error");
			return ;
		}
		struct sockaddr_in rin;
    	rin.sin_family=AF_INET;
		rin.sin_port=htons(PORT);
		rin.sin_addr.s_addr=inet_addr(IP);
		if(bind(sfd,(struct sockaddr*)&rin,sizeof(rin))==-1){
			perror("bind error");
			return ;
		}
		printf("bind success\n");
		struct sockaddr_in sin;
    	sin.sin_family=AF_INET;
		sin.sin_port=htons(SER_PORT);
		sin.sin_addr.s_addr=inet_addr(SER_IP);	
		socklen_t sin_size = sizeof(sin);  
		//发送下载请求
		sendto(sfd,data,len,0,(struct sockaddr*)&sin,sizeof(sin));
		int count=1;
		*p1=htons(3);
		short* p10=data+2;
		while(1){
			*p10=htons(count);
			int ress=read(fp,data+4,512);
			if(ress==0){break;}
			sendto(sfd, data, sizeof(data), 0, (struct sockaddr*)&sin, sin_size);
			count++;


		}

	close(fp);
}
int main(int argc, const char *argv[])
{

	printf("1.下载2.上传");
	printf("请输入>>>");
	int flag=0;
	scanf("%d",&flag);
	while(getchar()!=10);
	char data[516]="";
	short* p1=data;
	char* p2=data+2;
	if(flag==1){
		download(data,p1,p2);
	}else if(flag==2){
		transmit(data,p1,p2);
	}
	
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

03_信号和槽

信号和槽 系统的信号和槽自定义信号和槽Lambda表达式 系统的信号和槽 下面我们完成一个小功能&#xff0c;上面我们已经学习了按钮的创建&#xff0c;但是还没有体现出按钮的功能&#xff0c;按钮最大的功能也就是点击后触发一些事情&#xff0c;比如我们点击按钮&#xff0c;…

12.哀家要长脑子了!

1.189. 轮转数组 - 力扣&#xff08;LeetCode&#xff09; ​ 方法一&#xff1a; 要注意这个k是可以大于0的&#xff0c;所以旋转数组的时候要一直保证是在1-n的范围内&#xff1a;%实现 把k个元素旋转放到前面&#xff0c;前面n-k个元素是向后移动的。 class Solution { …

【Phytium】飞腾D2000 UEFI/EDK2 适配 RTC(IIC SD3077)

文章目录 0. env1. 软件2. 硬件 10. 需求1. 硬件2. 软件 20. DatasheetCPURTC 30. 调试步骤1. 硬件环境搭建2. UEFI 开发环境搭建3. 修改步骤1. UEFI 中使能RTC驱动、配置RTC信息等1.1 使能RTC驱动1.2 修改RTC对应的IIC配置信息1.3 解决驱动冲突1.4 验证波形 2. 修改对应RTC驱动…

[lesson36]经典问题解析三

经典问题解析三 关于赋值的疑问 什么时候需要重载赋值操作符&#xff1f;编译器是否提供默认的赋值操作&#xff1f; 编译器为每个类默认重载了赋值操作符 默认的赋值操作符仅完成浅拷贝 当需要进行深拷贝时必须重载赋值操作符 赋值操作符与拷贝构造函数有相同的存在意义 …

零基础入门测试该学什么?超全整理,照着学就对了!

对于很多小白而言&#xff0c;想要转行软件测试岗位&#xff0c;却又怕自己从来没有接触过计算机&#xff0c;底子很薄弱&#xff0c;从而还没开始就打起了退堂鼓。也有许多初学者&#xff0c;在入门的过程中&#xff0c;苦于不知道该学什么&#xff0c;又该从何学起&#xff0…

代码随想录算法训练营第四十二天| 二维背包、一维背包、LeetCode 416.分割等和子集

一、二维背包 文章讲解/视频讲解&#xff1a;https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html 状态&#xff1a;已解决 1.背包问题介绍 背包问题实则是一类问题的集合&#xff0c;有好多不同小类型&#xff0c…

单位优秀信息宣传员告诉你向媒体投稿你不知道的好方法

作为基层社区信息宣传工作队伍中的一员,我刚开始接手单位的信息宣传投稿任务时,真的是一片茫然。没有任何媒体编辑的熟人朋友,我只能硬着头皮,一家家地去联系媒体,沟通投稿的事宜。这个过程真的是既费事又费力,每次投稿都像是在茫茫大海中寻找那一丝被认可的机会。 因为媒体对稿…

VLAN Mapping原理描述

基本原理 路由器收到带Tag的数据报文后&#xff0c;根据配置的VLAN Mapping方式&#xff0c;决定替换外层Tag中的VLAN ID或优先级&#xff1b;然后进入MAC地址学习阶段&#xff0c;根据源MAC地址映射后的VLAN ID刷新MAC地址表项&#xff1b;根据目的MAC映射后VLAN ID查找MAC地…

T细胞耗竭

目录 T Cell Exhaustion T 细胞衰竭路径上的细胞和分子路标 研究起源 介绍 T 细胞耗竭的发生路径 耗尽的T细胞亚群的解剖分离和迁移 持续TCR刺激的收益递减 通过共调节受体进行发育微调 细胞因子介导的耗尽T细胞亚群的特异性 T细胞耗竭和表观遗传 T Cell Exhaustion…

面试问答之转账功能测试点详解

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

快速排序题目SelectK问题

力扣75.颜色分类 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sor…

数据库(mysql)-连接嵌套查询-2

子查询 MySQL中的子查询&#xff08;Subquery&#xff09;是嵌套在其他SQL查询中的查询。子查询可以出现在SELECT、FROM或WHERE子句中&#xff0c;并用于返回将被用于外部查询的数据。子查询的结果可以是一个单一的值、一行、一列或多行多列的数据集。 单行单列查询 实例 #查…

一款挺不错网站维护页面HTML源码

一款挺不错网站维护页面源码&#xff0c;单HTML不需要数据库&#xff0c;上传到你的虚拟机就可以用做维护页面还不错&#xff0c;用处多。。 源码下载 一款挺不错网站维护页面源码

【智能算法】鱼鹰优化算法(OOA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2023年&#xff0c;M Dehghani等人受到自然界鱼鹰狩猎行为启发&#xff0c;提出了鱼鹰优化算法&#xff08;Osprey Optimization Algorithm, OOA&#xff09;。 2.算法原理 2.1算法思想 OOA基本灵…

网络爬虫:定义、应用及法律道德考量

网络爬虫技术在当今数据驱动的世界中发挥着重要作用。本文将从网络爬虫的定义和主要功能&#xff0c;其在业界的应用实例&#xff0c;以及涉及的法律和道德问题三个方面进行深入探讨。 1. 爬虫的定义和主要功能 网络爬虫&#xff0c;也称为网页爬虫或蜘蛛&#xff0c;是一种…

苹果与印度深入洽谈,开启新业务 | 百能云芯

印度经济时报&#xff08;ET&#xff09;引述知情人士报导&#xff0c;苹果&#xff08;Apple&#xff09;正和 Murugappa 集团和塔塔集团旗下的Titan公司深入洽谈&#xff0c;将由这两家印度业者组装、甚至生产 iPhone 所用的相机模组。 苹果正将iPhone供应链向中国大陆以外地…

SpringBoot学习(三)数据访问、基础特性、核心原理

文章目录 数据访问示例自动配置原理jdbc场景自动配置数据源等基本信息MyBatisAutoConfiguration配置MyBatis整合流程 基础特性SpringApplication自定义banner自定义SpringApplicationFluentBuilder API Profiles使用指定环境环境激活环境包含 Profiles配置文件 外部化配置配置优…

JVM结构化体系

目录 目录 1.JVM 简介 1.1. 如何理解 JVM 呢&#xff1f; 1.2. 市场主流 JVM 分析&#xff1f; 1.3. 为什么要学习 JVM&#xff1f; 1.4. 字节码底层是如何执行呢&#xff1f; 如何理解 JIT 呢&#xff1f; 为什么 JVM 中解释执行与编译执行的并存&#xff08;混合模式&…

新手教程 | 2024年最新Vmware17安装教程及许可证(详细图文)

目录 前言&#xff1a; 一、VMware Workstation 17 Pro 简介 二、下载安装&#xff08;以Windows为例&#xff09; 三、许可证 四、检查是否安装成功 前言&#xff1a; 重新装电脑后&#xff0c;安装虚拟机 一、VMware Workstation 17 Pro 简介 VMware Workstation 17 …

【JavaWeb】Day46.Mybatis——入门

JDBC介绍 通过Mybatis可以很方便的进行数据库的访问操作。其实java语言操作数据库&#xff0c;只能通过一种方式&#xff1a;使用sun公司提供的 JDBC 规范。Mybatis框架&#xff0c;就是对原始的JDBC程序的封装。 JDBC&#xff1a; ( Java DataBase Connectivity )&#xff0c…
最新文章