网络编程day04(网络属性函数、广播、组播、TCP并发)

news2025/1/12 4:10:15

今日任务

对于newfd的话,最好是另存然后传入给分支线程,避免父子线程操作同一个文件描述符

1.广播:

接收端

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
 #include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>



#define ERR_MSG(msg) do{\
	perror(msg);\
	fprintf(stderr,"__%d__",__LINE__);\
}while(0)
#define IP "192.168.125.255"
#define PORT 8888
/*
 * function:    广播,接收方
 * @param [ in] 
 * @param [out] 
 * @return      
 */

int main(int argc, const char *argv[])
{
	//创建报式套接字
	int sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd<0){
		ERR_MSG("socket");
		return -1;
	}
	puts("socket success");
	//绑定IIF(P和端口号(广播ip)
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_port=htons(PORT);
	addr.sin_addr.s_addr=inet_addr(IP);
	socklen_t addrlen=sizeof(addr);
	if(bind(sfd,(struct sockaddr*)&addr,addrlen)<0){
		ERR_MSG("bind");
	}
	puts("bind success");
	//存储发送方地址消息
	struct sockaddr_in source_addr;
	socklen_t source_addrlen=sizeof(source_addr);
	//循环接受消息
	char buf[128]="";
	while(1){
		bzero(buf,sizeof(buf));
		int recv_res=recvfrom(sfd,&buf,sizeof(buf),0,(struct sockaddr*)&source_addr,&source_addrlen);
		if(recv_res<0){
			ERR_MSG("recvfrom");
			return -1;
		}
		puts("recvfrom success");
		printf("[%s:%d]:%s\n",inet_ntoa(source_addr.sin_addr),ntohs(source_addr.sin_port),buf);
	}
	//关闭
	close(sfd);
	return 0;
}

发送端

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
 #include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>



#define ERR_MSG(msg) do{\
	perror(msg);\
	fprintf(stderr,"__%d__",__LINE__);\
}while(0)
#define IP "192.168.125.255"
#define PORT 8888
/*
 * function:    广播,发送方
 * @param [ in] 
 * @param [out] 
 * @return      
 */

int main(int argc, const char *argv[])
{
	//创建报式套接字
	int sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd<0){
		ERR_MSG("socket");
		return -1;
	}
	puts("socket success");
	//设置允许广播
	int optval=1;//非0为允许
	socklen_t optlen=sizeof(optval);
	if(setsockopt(sfd,SOL_SOCKET,SO_BROADCAST,&optval,optlen)<0){
		ERR_MSG("setsockopt");
		return -1;
	}

	//IP和端口号(广播ip)
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_port=htons(PORT);
	addr.sin_addr.s_addr=inet_addr(IP);
	socklen_t addrlen=sizeof(addr);
	//循环发送消息
	char buf[128]="";
	while(1){
		bzero(buf,sizeof(buf));
		printf("请输入>>>");
		fgets(buf,sizeof(buf),stdin);
		buf[strlen(buf)-1]='\0';
		if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&addr,addrlen)<0){
			ERR_MSG("sendto");
			return -1;
		}
		puts("sendto success");
		}
	//关闭
	close(sfd);
	return 0;
}

2.组播

接收端

代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>                                                                   
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>

#define ERR_MSG(msg) do{\
	perror(msg);\
	fprintf(stderr,"__%d__",__LINE__);\
}while(0)
#define IP "192.168.125.2"
#define PORT 8888
#define GRP_IP "224.1.2.3"
/*
 * function:    组播:接收方
 * @param [ in] 
 * @param [out] 
 * @return      
 */
int main(int argc, const char *argv[])
{
	//创建报式套接字
	int sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd<0){
		ERR_MSG("socket");
		return -1;
	}
	puts("socket success");

	//加入多播组
	struct ip_mreqn mq;

    mq.imr_multiaddr.s_addr = inet_addr(GRP_IP);    //组播IP
    mq.imr_address.s_addr   = inet_addr(IP);    //本机IP,ifconfig
    mq.imr_ifindex = 2;         //网络设备索引号

	if(setsockopt(sfd,IPPROTO_IP, IP_ADD_MEMBERSHIP,&mq,sizeof(mq))<0){
		ERR_MSG("setsockopt");
		return -1;
	}


	//绑定IIF(P和端口号(广播ip)
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_port=htons(PORT);
	addr.sin_addr.s_addr=inet_addr(GRP_IP);
	socklen_t addrlen=sizeof(addr);
	if(bind(sfd,(struct sockaddr*)&addr,addrlen)<0){
		ERR_MSG("bind");
	}
	puts("bind success");


	//接受对方地址信息
	struct sockaddr_in source_addr;
	socklen_t source_addrlen=sizeof(source_addr);

	char buf[128]="";

	while(1){
	
		//接收消息
		bzero(buf,sizeof(buf));
		int recv_res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&source_addr, &source_addrlen);
        if(recv_res < 0)
        {
            ERR_MSG("recvfrom");
            return -1;
        }

        printf("[%s:%d] : %s\n", \
                inet_ntoa(source_addr.sin_addr), ntohs(source_addr.sin_port), buf);
	}
	//关闭
	close(sfd);
	return 0;
}

发送端

代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>                                                                   
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>

#define ERR_MSG(msg) do{\
	perror(msg);\
	fprintf(stderr,"__%d__",__LINE__);\
}while(0)
#define IP "192.168.125.2"
#define PORT 8888
#define GRP_IP "224.1.2.3"
/*
 * function:    组播:发送方
 * @param [ in] 
 * @param [out] 
 * @return      
 */
int main(int argc, const char *argv[])
{
	//创建报式套接字
	int sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd<0){
		ERR_MSG("socket");
		return -1;
	}
	puts("socket success");

	//绑定IIF(P和端口号(广播ip)
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_port=htons(PORT);
	addr.sin_addr.s_addr=inet_addr(GRP_IP);
	socklen_t addrlen=sizeof(addr);
	if(bind(sfd,(struct sockaddr*)&addr,addrlen)<0){
		ERR_MSG("bind");
	}
	puts("bind success");



	char buf[128]="";

	while(1){
	
		//发送消息
		bzero(buf,sizeof(buf));
		  printf("请输入>>> ");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf)-1] = 0;

        //发送数据, 主动发送给指定接收放,例如这里可以主动发给接收方
        if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, sizeof(addr)) < 0)
        {
            ERR_MSG("sendto");
            return -1;
        }
        printf("sendto success\n");
		}
	//关闭
	close(sfd);
	return 0;
}

3.TCP并发

多线程

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
//自定义报错提示
#define ERR_MSG(msg) do{\
	fprintf(stderr,"__%d__",__LINE__);\
	perror(msg);\
}while(0)
#define SER_PORT 8888
#define SER_IP "192.168.125.2"
/*
 * function:    TCP服务端
 * @param [ in] 
 * @param [out] 
 * @return      
 */

int recv_send(int cfd,struct sockaddr_in cli_addr);
void handle(int sig){
	while(waitpid(-1,NULL,WNOHANG)>0);
	return ;
}

int main(int argc, const char *argv[])
{
	//监听回收僵尸进程
	if(signal(SIGCHLD,handle)==SIG_ERR){
		ERR_MSG("signal");
		return -1;
	}

	//1.创建socket套接字,
	int sfd=socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0){
		ERR_MSG("socket");
		return -1;
	}
	puts("socket create");

	//允许端口快速复用
	int reuse = 1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
	printf("允许端口快速复用成功\n");
	//2.绑定服务器IP和端口号bind
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_port=htons(SER_PORT);
	addr.sin_addr.s_addr=inet_addr(SER_IP);
	if(bind(sfd,(struct sockaddr*)&addr,sizeof(addr))<0){
		ERR_MSG("bind");
		return -1;
	}
	puts("bind success");


	//3.建立监听listen
	if(listen(sfd,128)<0){
		ERR_MSG("listen");
		return -1;
	}
	puts("listen suucess");


	//4.等待客户端连接, accept
	struct sockaddr_in cli_addr;
	socklen_t cli_addrlen=sizeof(cli_addr);
	pid_t pid;
	while(1){
		int cfd=accept(sfd,(struct sockaddr*)&cli_addr,&cli_addrlen);
		if(cfd<0){
			ERR_MSG("accept");
			return -1;
		}
		puts("accept");
		pid=fork();
		if(pid==0){
			//子进程执行信息收发
			recv_send(cfd,cli_addr);
			exit(0);
		}else if(pid<0){
			ERR_MSG("fork");
			return -1;
		}
		close(cfd);

	}
	//6.关闭
	close(sfd);


	return 0;
}
int recv_send(int cfd,struct sockaddr_in cli_addr){
	//5.接受发送消息recv;send
	char buf[128];
	while(1){
		bzero(buf,sizeof(buf));
		int recv_res=recv(cfd,buf,sizeof(buf),0);

		if(recv_res<0){
			ERR_MSG("recv");
			return -1;
		}else if(recv_res==0){
			printf("socket peer has shutdown\n");
			break;
		}
		puts("recv success");
		printf("[%s:%d]:%s\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port),buf);
		if(strcmp(buf,"quit")==0)
			break;

		strcat(buf,"-----i has received");
		int send_res=send(cfd,buf,sizeof(buf),0);
		if(send_res<0){
			ERR_MSG("send");
			return -1;
		}
		puts("send success");
	}
}

多进程

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

//自定义报错提示
#define ERR_MSG(msg) do{\
	fprintf(stderr,"__%d__",__LINE__);\
	perror(msg);\
}while(0)
#define SER_PORT 8888
#define SER_IP "192.168.125.2"
struct cliMsg{
	int cfd;
	struct sockaddr_in cli_addr;
};
/*
 * function:    TCP服务端
 * @param [ in] 
 * @param [out] 
 * @return      
 */
void* recv_send(void*arg);
int main(int argc, const char *argv[])
{
	//1.创建socket套接字,
	int sfd=socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0){
		ERR_MSG("socket");
		return -1;
	}
	puts("socket create");

	//允许端口快速复用
	int reuse = 1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
	printf("允许端口快速复用成功\n");
	//2.绑定服务器IP和端口号bind
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_port=htons(SER_PORT);
	addr.sin_addr.s_addr=inet_addr(SER_IP);
	if(bind(sfd,(struct sockaddr*)&addr,sizeof(addr))<0){
		ERR_MSG("bind");
		return -1;
	}
	puts("bind success");


	//3.建立监听listen
	if(listen(sfd,128)<0){
		ERR_MSG("listen");
		return -1;
	}
	puts("listen suucess");


	//4.等待客户端连接, accept
	struct sockaddr_in cli_addr;
	socklen_t cli_addrlen=sizeof(cli_addr);
	pthread_t pth;
	while(1){

		int cfd=accept(sfd,(struct sockaddr*)&cli_addr,&cli_addrlen);
		if(cfd<0){
			ERR_MSG("accept");
			return -1;
		}
		puts("accept");
		struct cliMsg climsg;
		climsg.cfd=cfd;
		climsg.cli_addr=cli_addr;
		//创建调用线程执行
		if(pthread_create(&pth,NULL,recv_send,(void *)&climsg)!=0){
			fprintf(stderr,"pthread_create failed __%d__\n",__LINE__);
			return -1;
		}
		pthread_detach(pth);

	}
	close(sfd);

	return 0;
}
void* recv_send(void*arg){
	//5.接受发送消息recv;send
	int cfd=((struct cliMsg*)arg)->cfd;
	struct sockaddr_in cli_addr=((struct cliMsg*)arg)->cli_addr;

	char buf[128];
	while(1){
		bzero(buf,sizeof(buf));
		int recv_res=recv(cfd,buf,sizeof(buf),0);

		if(recv_res<0){
			ERR_MSG("recv");
			 break;
		}else if(recv_res==0){
			printf("socket peer has shutdown\n");
			break;
		}
		puts("recv success");
		printf("[%s:%d]:%s\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port),buf);
		if(strcmp(buf,"quit")==0)
			break;

		strcat(buf,"-----i has received");
		int send_res=send(cfd,buf,sizeof(buf),0);
		if(send_res<0){
			ERR_MSG("send");
			break;
		}
		puts("send success");
	}
	close(cfd);
	pthread_exit(NULL);
}

今日思维导图

不知道最近确实是脑子比较慢,还是拖拉,做事太慢了,tcp的代码还没复敲;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习文本预处理利器:Tokenizer详解

目录 1 Tokenizer 介绍 1.1 Tokenizer定义 1.2 Tokenizer方法 1.3 Tokenizer属性 2 Tokenizer文本向量化 2.1 英文文本向量化 2.2 中文文本向量化 3 总结 1 Tokenizer 介绍 Tokenizer是一个用于向量化文本&#xff0c;将文本转换为序列的类。计算机在处理语言文字时&…

对本地的静态html文件发送http请求

需要对本地的html文件&#xff0c;或者说静态网页发送请求&#xff0c;只有前端页面&#xff0c;没有后端。前端的文件基本都有。 文件链接&#xff1a;D:/mystudysoft/weixinkaifa/WeChat%20Files/wxid_inmlsqlnnpqs22/FileStorage/File/2023-09/%E5%BE%B7%E5%9B%BD%E4%BA%…

聚观早报|高德发布安全出行大模型;小鹏G9焕新上市

【聚观365】9月21日消息 高德发布安全出行大模型 小鹏G9焕新上市 妙鸭相机上线免费版 Redmi Note 13 Pro支持IP68 Neuralink将进行首次人体临床试验 高德发布安全出行大模型 高德发布了安全出行大模型。据介绍&#xff0c;安全出行大模型基于高德的地图大数据、位置大数据…

FPGA project : DS18B20

本想着一天发一个实验的&#xff0c;这个ds18b20&#xff0c;耗时两天。代码写了两次&#xff0c;呜呜~ 由于第二次写代码没画时序图&#xff0c;所以代码和时序图一些参数有些不一致&#xff0c;但问题不大。 这里有几件事情值得一提&#xff1a; 1&#xff1a;关于状态机的…

Linux系统编程——网络编程的学习

Linux系统编程学习相关博文 Linux系统编程——文件编程的学习Linux系统编程——进程的学习Linux系统编程——进程间通信的学习Linux系统编程——线程的学习 Linux系统编程——网络编程的学习 一、概述1. TCP/UDP2. 端口号3. 字节序4. Sockt服务器和客户端的开发步骤1. 服务器2…

网络编程 day4

1->广播模型 接收方 发送方 2->组播模型 接收方 发送方 3->多进程并发服务器 4->多线程并发服务器

openssl 交叉编译(uclibc)

参考文章 openssl 交叉编译_GeYi1998的博客-CSDN博客 本地实际操作一遍,和网上的文章有些不同. 先下载源码 /source/index.html 使用 1.1.1w的版本,最新的3.0.11试了,编译不过,很多gcc的写法问题(error: initializer element is not constant) 解压到 Document 目录下, h…

视频汇聚/视频云存储/视频监控管理平台EasyCVR分发rtsp流起播慢优化步骤详解

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

iOS自动化测试方案(一):MacOS虚拟机保姆级安装Xcode教程

文章目录 一、环境准备二、基础软件三、扩展&#xff1a;usb拓展插件 一、环境准备 1、下载VMware虚拟机的壳子&#xff0c;安装并注册软件(可以百度注册码)&#xff0c;最新版本&#xff1a;v17 2、下MacOS系统iOS镜像文件&#xff0c;用于vmware虚拟机安装&#xff0c;当前镜…

如何用一行CSS实现10种现代布局

现代 CSS 布局使开发人员只需按几下键就可以编写十分有意义且强大的样式规则。上面的讨论和接下来的帖文研究了 10 种强大的 CSS 布局&#xff0c;它们实现了一些非凡的工作。 超级居中&#xff1a;place-items: center 对于第一个“单行”布局&#xff0c;让我们解决所有 CSS…

使用 PyTorch 的计算机视觉简介 (3/6)

一、说明 在本单元中&#xff0c;我们将了解卷积神经网络&#xff08;CNN&#xff09;&#xff0c;它是专门为计算机视觉设计的。 卷积层允许我们从图像中提取某些图像模式&#xff0c;以便最终分类器基于这些特征。 二、卷积神经网络 计算机视觉不同于通用分类&#xff0c;因…

虚拟机中window/ubuntu系统如何联网?

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 &#xff08;1&#xff09;VMware虚拟机中Windows11无法连接网络 &#xff08;2&#xff09;图解vmware虚拟机win8无线上网 &#xff08;3&#xff09;VMware中VMnet0、VMnet1、VMnet8是什么 &…

PyTorch深度学习(七)【循环神经网络-提高】

数据集文末分享。 模型&#xff1a; 做完padding之后&#xff0c;就可以转换为张量了。 bidirectional是是否使用双向RNN: 输出隐层两个&#xff1a; 代码&#xff1a; import csvimport timeimport matplotlib.pyplot as pltimport numpy as npimport mathimport gzip # 用…

巨人互动|Facebook海外户Facebook内容的类型

随着人们日益依赖的社交媒体来进行信息获取与交流&#xff0c;Facebook作为全球最大的社交媒体平台之一&#xff0c;那么Facebook的内容都有哪些类型呢&#xff1f;下面小编来讲讲吧&#xff01; 1、实时发生的事 我们需要实时了解时事动态&#xff0c;这样可以使用户对品牌发…

【网络层】IP协议

文章目录 IP协议1. 前提认识(1) IP的定位和作用(2) IP地址的构成(3) 基本概念 2. 协议头格式(1) 两个核心问题 3. 网段划分(重要)(1) 为什么要网段划分(2) 概念(3) 子网划分方案(4) 模拟子网划分 4. 特殊的IP地址5. IP地址的数量限制6. 私有IP地址和公网IP地址7. 路由及路由表(…

学习记忆——宫殿篇——记忆宫殿——记忆桩——火车+外院+客厅+卧室

护板 警示灯 烟筒 采集箱 司炉室 桥 电线杆 棚顶 车厢 护栏 植物 石阶 水泥台 竹门 树干 躺椅 柱子 墙 池 洞 方灯 枕头 树 浴池 墙 射灯 藤条 浴巾框 耳环 窗户 灯 沙发 壁炉 吊灯 兵马俑 门 石佛 沙发椅 圆木 弧形木箱盖 床 窗帘 画板 纸伞 花 沙发背 颜料 抽屉

Hadoop-sqoop

sqoop 1. Sqoop简介及原理 简介&#xff1a; Sqoop是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(mysq1.postgresql..)间进行数据的传递&#xff0c;可以将一个关系型数据库&#xff08;例如: MySQL ,Oracle ,Postgres等&#xff09;中的数据导进到Hadoop 的HDFS中&…

【AI视野·今日Robot 机器人论文速览 第三十七期】Wed, 20 Sep 2023

AI视野今日CS.Robotics 机器人学论文速览 Wed, 20 Sep 2023 Totally 53 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Machine Learning-Driven Burrowing with a Snake-Like Robot Authors Sean Even, Holden Gordon, Hoeseok Yang, Yasemin Ozk…

《软件方法》第1章2023版连载(03)建模工作流

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 1.2 建模工作流 1.2.1 建模工作流ABCD 如何能做好需求和设计&#xff0c;达到“低成本制造好卖的系统”的目标&#xff1f;并非喊喊口号就可以&#xff0c;需要静下心来学习和实践一…

基于知识蒸馏的两阶段去雨去雪去雾模型学习记录(一)

前面完成了基于知识蒸馏的去雨去雪去雾模型大的部署与训练&#xff0c;下面则进行代码的学习。 使用debug的方式进行代码的学习。 首先是网络结构展示&#xff1a;轻易不要打开&#xff0c;这个模型太复杂了。说到底倒不是多复杂&#xff0c;就是层数太多了 Net((conv_input):…