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

今日任务

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

------------在tcp多线程服务端----------

如果使用全局变量,或者指针方式间接访问,会导致所有线程共用一份newfd和cin,那么newfd和cin会被覆盖

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);    //组播IPmq.imr_address.s_addr   = inet_addr(IP);    //本机IP,ifconfigmq.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和端口号bindstruct 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.建立监听listenif(listen(sfd,128)<0){ERR_MSG("listen");return -1;}puts("listen suucess");//4.等待客户端连接, acceptstruct 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;sendchar 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和端口号bindstruct 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.建立监听listenif(listen(sfd,128)<0){ERR_MSG("listen");return -1;}puts("listen suucess");//4.等待客户端连接, acceptstruct 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;sendint 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.rhkb.cn/news/143487.html

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

相关文章

冲刺十五届蓝桥杯P0001阶乘求和

文章目录 题目描述思路分析代码解析 题目描述 思路分析 阶乘是蓝桥杯中常考的知识。 首先我们需要知道 int 和long的最大值是多少。 我们可以知道19的阶乘就已经超过了long的最大值&#xff0c;所以让我们直接计算202320232023&#xff01;的阶乘是不现实的。 所以我们需要…

基于Linux socket聊天室-多线程服务器模型(01)

​前言 socket在实际系统程序开发当中&#xff0c;应用非常广泛&#xff0c;也非常重要。实际应用中服务器经常需要支持多个客户端连接&#xff0c;实现高并发服务器模型显得尤为重要。高并发服务器从简单的循环服务器模型处理少量网络并发请求&#xff0c;演进到解决C10K&…

什么是推挽电路?

推挽电路原理&#xff1a; 可以简单理解为推和拉&#xff1b; 此电路总共用到两个元器件&#xff0c;对应图中的Q1----NPN三极管&#xff0c;Q2----PNP三极管&#xff0c;两个电阻R1和R2起到限流的作用&#xff1b;两个三极管的中间对应信号的输出。 下面就举例说明是如何工作的…

基于JAVA,SpringBoot和Vue的前后端分离的求职招聘系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 这个系统的研发背景是…

时序预测 | MATLAB实现POA-CNN-BiLSTM鹈鹕算法优化卷积双向长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现POA-CNN-BiLSTM鹈鹕算法优化卷积双向长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现POA-CNN-BiLSTM鹈鹕算法优化卷积双向长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现POA-CNN-BiLSTM鹈鹕算…

使用SPY++查看窗口信息去排查客户端UI软件问题

目录 1、使用SPY查看窗口的信息 2、使用SPY查看某些软件UI窗口用什么UI组件实现的 2.1、查看海康视频监控客户端安装包程序 2.2、查看华为协同办公软件WeLink 2.3、查看字节协同办公软件飞书 2.4、查看最新版本的Chrome浏览器 2.5、查看小鱼易连视频会议客户端软件 2.6…

第十四届蓝桥杯大赛软件赛决赛 C/C++ 大学 B 组 试题 A: 子 2023

[蓝桥杯 2023 国 B] 子 2023 试题 A: 子 2023 【问题描述】 小蓝在黑板上连续写下从 1 1 1 到 2023 2023 2023 之间所有的整数&#xff0c;得到了一个数字序列&#xff1a; S 12345678910111213 ⋯ 20222023 S 12345678910111213\cdots 20222023 S12345678910111213⋯2…

讯飞星火认知大模型Java后端接口

文章目录 1.免费申请星火大模型套餐2.Java后端接口说明2.1 项目地址2.2 项目说明2.3 项目结构2.4 项目代码&#x1f340; maven 依赖&#x1f340; application.yml 配置文件&#x1f340; config 包&#x1f4cc; XfXhConfig &#x1f340; dto 包&#x1f4cc; MsgDTO&#x…

element中使用el-steps 进度条效果demo(整理)

<template><div class"margin-top20"><!-- align-center 不要居中就去掉 --><!-- process-status 这几个参数值&#xff1a;改变颜色 wait / process / finish / error / --><!-- active 到第几个是绿色 --><el-steps :space&qu…

深度解读F5:从企业级负载均衡到云原生应用服务

上世纪九十年代&#xff0c;Internet 的快速发展催生了大量在线网站&#xff0c;Web 访问量迅速提升。在互联网泡沫破灭以前&#xff0c;这个领域基本是围绕如何对 Web 网站进行负载均衡与优化。因而在早期&#xff0c;也会有“Web 交换机”的说法。从1997年 F5 发布了 BIG-IP …

黑马JVM总结(二十五)

&#xff08;1&#xff09;字节码指令-cinit 构造方法可以分为两类&#xff0c;一类是cinit 一类init cinit是整个类的构造方法 putstatic&#xff1a;进行static变量的赋值&#xff0c;是到常量池里找到名字一个叫做i的变量 &#xff08;2&#xff09;字节码指令-init in…

JimuReport积木报表 v1.6.2 版本正式发布—开源免费的低代码报表

项目介绍 一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于excel操作风格&#xff0c;通过拖拽完成报…

mysql面试题2:说一说MySQL的架构设计?一条 MySQL 语句执行的步骤?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说MySQL的架构设计? MySQL的架构设计主要包括以下几个组件: 连接器(Connector):负责与客户端建立连接,并进行身份验证和授权。 查询缓存…

BFS专题7 多终点迷宫问题

题目&#xff1a; 样例&#xff1a; 输入 3 3 0 0 0 1 0 0 0 1 0 输出 0 1 2 -1 2 3 -1 -1 4 思路&#xff1a; 单纯的 BFS 迷宫问题&#xff0c;只是标记一下每个点的 step&#xff0c;注意初始化答案数组都为 -1. 代码详解如下&#xff1a; #include <iostream> #…

常用接口测试工具

首先&#xff0c;什么是接口呢&#xff1f; 接口一般来说有两种&#xff0c;一种是程序内部的接口&#xff0c;一种是系统对外的接口。 系统对外的接口&#xff1a;比如你要从别的网站或服务器上获取资源或信息&#xff0c;别人肯定不会把数据库共享给你&#xff0c;他只能给你…

五、3d场景的卡片展示的创建

在我们3d的开发中&#xff0c;对某一些建筑和物体进行解释说明是非常常见的现象&#xff0c;那么就不得不说卡片的展示了&#xff0c;卡片展示很友好的说明了当前物体的状态&#xff0c;一目了然&#xff0c;下面就是效果图。 它主要有两个方法来实现&#xff0c;大量的图片建议…

最近很火的AIGC人工智能之AI赋能运营(巧用ChatGPT轻松上手新媒体)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

阿里云服务器技术创新、网络技术和数据中心技术说明

阿里云服务器技术创新、网络技术创新、数据中心技术创新和智能运维&#xff1a;云服务器方升架构、自研硬件、自研存储硬件AliFlash和异构计算加速平台&#xff0c;以及全自研网络系统技术创新和数据中心巴拿马电源、液冷技术等技术创新说明&#xff0c;阿里云百科分享阿里云服…

算法-堆/多路归并-查找和最小的 K 对数字

算法-堆/多路归并-查找和最小的 K 对数字 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/find-k-pairs-with-smallest-sums/description/?envTypestudy-plan-v2&envIdtop-interview-150 1.2 题目描述 2 优先级队列构建大顶堆 2.1 思路 将两个数字的和放入大…

Spring面试题23:Spring支持哪些事务管理类型?Spring框架的事务管理有哪些优点?你更倾向用哪种事务管理类型?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Spring支持哪些事务管理类型? Spring 支持以下几种事务管理类型: 编程式事务管理:通过在代码中显式地使用事务管理 API(如 TransactionTempla…