4.32UDP通信实现 4.33广播 4.34组播 4.35本地套接字通信

news/2024/12/22 14:05:15/

4.32UDP通信实现

在这里插入图片描述在这里插入图片描述
![在这在这里插入图片描述
udp_client.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>int main() {// 1.创建一个通信的socketint fd = socket(PF_INET, SOCK_DGRAM, 0);if(fd == -1) {perror("socket");exit(-1);}   // 服务器的地址信息struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(9999);inet_pton(AF_INET, "127.0.0.1", &saddr.sin_addr.s_addr);int num = 0;// 3.通信while(1) {// 发送数据char sendBuf[128];sprintf(sendBuf, "hello , i am client %d \n", num++);sendto(fd, sendBuf, strlen(sendBuf) + 1, 0, (struct sockaddr *)&saddr, sizeof(saddr));// 接收数据int num = recvfrom(fd, sendBuf, sizeof(sendBuf), 0, NULL, NULL);printf("server say : %s\n", sendBuf);sleep(1);}close(fd);return 0;
}

udp_server.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>int main() {// 1.创建一个通信的socketint fd = socket(PF_INET, SOCK_DGRAM, 0);if(fd == -1) {perror("socket");exit(-1);}   struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(9999);addr.sin_addr.s_addr = INADDR_ANY;// 2.绑定int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));if(ret == -1) {perror("bind");exit(-1);}// 3.通信while(1) {char recvbuf[128];char ipbuf[16];struct sockaddr_in cliaddr;int len = sizeof(cliaddr);// 接收数据int num = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&cliaddr, &len);printf("client IP : %s, Port : %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),ntohs(cliaddr.sin_port));printf("client say : %s\n", recvbuf);// 发送数据sendto(fd, recvbuf, strlen(recvbuf) + 1, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));}close(fd);return 0;
}

4.33广播

向子网中多台计算机发送消息,并且子网中所有的计算机都可以接收到发送方发送的消息,每个广播消息都包含一个特殊的IP地址,这个IP中子网内主机标志部分的二进制全部为1.
a、只能在局域网中使用
b、客户端需要绑定服务器广播使用的端口,才可以接收到广播消息
在这里插入图片描述

//设置广播属性的函数
int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t optlen);-sockfd:文件描述符-level:SOL_SOCKET-optname:SO_BROADCAST-optval:int类型的值,为1表示允许广播-optlen:optval的大小

bro_server.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>int main(){//1、创建一个通信的socketint fd=socket(PF_INET,SOCK_DGRAM,0);if(fd==-1){perror("socket");exit(-1);}//2、设置广播属性int op=1;setsockopt(fd,SOL_SOCKET,SO_BROADCAST,&op,sizeof(op));//3、创建一个广播的地址struct sockaddr_in cliaddr;cliaddr.sin_family=AF_INET;cliaddr.sin_port=htons(9999);inet_pton(AF_INET,"192.168.193.255",&cliaddr.sin_addr.s_addr);//4、通信int num=0;while(1){char sendBuf[128];sprintf(sendBuf,"hello,client...%d\n",num++);//发送数据sendto(fd,sendBuf,strlen(sendBuf)+1,0,(struct sockaddr*) &cliaddr,sizeof(cliaddr));printf("广播的数据:%s\n",sendBuf);sleep(1);}close(fd);return 0;
}

bro_client.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>int main() {// 1.创建一个通信的socketint fd = socket(PF_INET, SOCK_DGRAM, 0);if(fd == -1) {perror("socket");exit(-1);}   struct in_addr in;// 2.客户端绑定本地的IP和端口struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(9999);addr.sin_addr.s_addr = INADDR_ANY;int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));if(ret == -1) {perror("bind");exit(-1);}// 3.通信while(1) {char buf[128];// 接收数据int num = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);printf("server say : %s\n", buf);}close(fd);return 0;
}

4.34组播

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
multi_server.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>int main() {// 1.创建一个通信的socketint fd = socket(PF_INET, SOCK_DGRAM, 0);if(fd == -1) {perror("socket");exit(-1);}   // 2.设置多播的属性,设置外出接口struct in_addr imr_multiaddr;// 初始化多播地址inet_pton(AF_INET, "239.0.0.10", &imr_multiaddr.s_addr);setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &imr_multiaddr, sizeof(imr_multiaddr));// 3.初始化客户端的地址信息struct sockaddr_in cliaddr;cliaddr.sin_family = AF_INET;cliaddr.sin_port = htons(9999);inet_pton(AF_INET, "239.0.0.10", &cliaddr.sin_addr.s_addr);// 3.通信int num = 0;while(1) {char sendBuf[128];sprintf(sendBuf, "hello, client....%d\n", num++);// 发送数据sendto(fd, sendBuf, strlen(sendBuf) + 1, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));printf("组播的数据:%s\n", sendBuf);sleep(1);}close(fd);return 0;
}

multi_client.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>int main() {// 1.创建一个通信的socketint fd = socket(PF_INET, SOCK_DGRAM, 0);if(fd == -1) {perror("socket");exit(-1);}   struct in_addr in;// 2.客户端绑定本地的IP和端口struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(9999);addr.sin_addr.s_addr = INADDR_ANY;int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));if(ret == -1) {perror("bind");exit(-1); }struct ip_mreq op;inet_pton(AF_INET, "239.0.0.10", &op.imr_multiaddr.s_addr);op.imr_interface.s_addr = INADDR_ANY;// 加入到多播组setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &op, sizeof(op));// 3.通信while(1) {char buf[128];// 接收数据int num = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);printf("server say : %s\n", buf);}close(fd);return 0;
}

4.35本地套接字通信

本地套接字的作用:本地的进程间通信
有关系的进程间的通信
没有关系的进程间的通信
本地套接字实现流程和网络套接字类似,一般采用TCP通信流程
在这里插入图片描述

//本地套接字通信的流程 -tcp
//服务器端
1、创建监听的套接字int lfd=socket(AF_UNIX/AF_LOCAL,SOCK_STREAM,0);
2、监听的套接字绑定本地的套接字文件->server端struct sockaddr_un addr;//绑定成之后,指定的sun_path中的套接字文件会自动生成bind(lfd,addr,len);
3、监听listen(lfd,100);
4、等待并接受连接请求struct sockaddr_un cliaddr;int len=sizeof(cliaddr);int cfd=accept(lfd,&cliaddr,len);
5、通信接收数据:read/rev发送数据:write/send
6、关闭连接close()//客户端的流程
1、创建通信的套接字int fd=socket(AF_UNIX/AF_LOCAL,SOCK_STREAM,0);
2、监听的套接字绑定本地的IP端口struct sockaddr_un addr;//绑定成功之后,指定的sun_path中的套接字文件会自动生成bind(lfd,addr,len);
3、连接服务端struct sockaddr_un serveraddr;connect(fd,&serveraddr,sizeof(serveraddr));
4、通信接收数据:read/recv发送数据:write/send
5、关闭连接close()
//头文件:sys/un.h
#define UNIX_PATH_MAX 108
struct sockaddr_un{sa_family_t sun_family;//地址族协议 af_localchar sun_path[UNIX_PATH_MAX];//套接字文件的路径,这是一个伪文件,大小永远=0 
}

ipc_server.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/un.h>int main() {unlink("server.sock");// 1.创建监听的套接字int lfd = socket(AF_LOCAL, SOCK_STREAM, 0);if(lfd == -1) {perror("socket");exit(-1);}// 2.绑定本地套接字文件struct sockaddr_un addr;addr.sun_family = AF_LOCAL;strcpy(addr.sun_path, "server.sock");int ret = bind(lfd, (struct sockaddr *)&addr, sizeof(addr));if(ret == -1) {perror("bind");exit(-1);}// 3.监听ret = listen(lfd, 100);if(ret == -1) {perror("listen");exit(-1);}// 4.等待客户端连接struct sockaddr_un cliaddr;int len = sizeof(cliaddr);int cfd = accept(lfd, (struct sockaddr *)&cliaddr, &len);if(cfd == -1) {perror("accept");exit(-1);}printf("client socket filename: %s\n", cliaddr.sun_path);// 5.通信while(1) {char buf[128];int len = recv(cfd, buf, sizeof(buf), 0);if(len == -1) {perror("recv");exit(-1);} else if(len == 0) {printf("client closed....\n");break;} else if(len > 0) {printf("client say : %s\n", buf);send(cfd, buf, len, 0);}}close(cfd);close(lfd);return 0;
}

ipc_client.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/un.h>int main() {unlink("client.sock");// 1.创建套接字int cfd = socket(AF_LOCAL, SOCK_STREAM, 0);if(cfd == -1) {perror("socket");exit(-1);}// 2.绑定本地套接字文件struct sockaddr_un addr;addr.sun_family = AF_LOCAL;strcpy(addr.sun_path, "client.sock");int ret = bind(cfd, (struct sockaddr *)&addr, sizeof(addr));if(ret == -1) {perror("bind");exit(-1);}// 3.连接服务器struct sockaddr_un seraddr;seraddr.sun_family = AF_LOCAL;strcpy(seraddr.sun_path, "server.sock");ret = connect(cfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if(ret == -1) {perror("connect");exit(-1);}// 4.通信int num = 0;while(1) {// 发送数据char buf[128];sprintf(buf, "hello, i am client %d\n", num++);send(cfd, buf, strlen(buf) + 1, 0);printf("client say : %s\n", buf);// 接收数据int len = recv(cfd, buf, sizeof(buf), 0);if(len == -1) {perror("recv");exit(-1);} else if(len == 0) {printf("server closed....\n");break;} else if(len > 0) {printf("server say : %s\n", buf);}sleep(1);}close(cfd);return 0;
}

http://www.ppmy.cn/news/679514.html

相关文章

Spring Boot 中的 RabbitMQ 的消息接收配置是什么,原理,如何使用

Spring Boot 中的 RabbitMQ 的消息接收配置是什么&#xff0c;原理&#xff0c;如何使用 RabbitMQ 是一个流行的消息队列系统&#xff0c;它可以用于在应用程序之间传递消息。Spring Boot 提供了对 RabbitMQ 的支持&#xff0c;我们可以使用 Spring Boot 中的 RabbitMQ 消息接…

iPhone备忘录内容怎么发送给微信好友

备忘录作为重要记录工具,深受大多数人的喜爱。它简单易用,可以快速记录我们生活和工作中的重要事项,减轻记忆负担,避免遗忘。然而,当我们需要与好友或同事共享某些重要备忘内容时,iPhone原生的备忘录应用却无法直接将内容发送给微信联系人,这一点略显不便。 将iPhone备忘录的内…

5V升压8.4V1A,给双节锂电池充电芯片-PL7501

概述 泛海微PL7022/B 是一款基于 CMOS 的双节可充电锂电池保护电路&#xff0c;它集高精度过电压充电保护、过电压放电保护、过电流充电保护、过电流放电保护、电池短路保护等性能于一身。 正常状态下&#xff0c;泛海微PL7022/B 由电池供电。当两节电池电压&#xff08;VBAT…

5V升压充电12.6V锂电池方案

在日常生活当中&#xff0c;5V升压12.6V芯片有很多选型&#xff0c;但5V升压充电12.6三节充电管理IC市面相对要少&#xff0c;HU5913一款5V升双节锂电池7.4V充电管理芯片HU5913,芯片采用外置MOS管&#xff0c;通过电阻来设计充电电流的大小&#xff0c;可匹配市面所有的5V适配器…

锂电池升压3V,3.3V,3.7V升压5V,9V,12V大小电流方案合集

分享单节锂电升压至5V9V12V&#xff0c;3W-30W电路&#xff0c;demo测试效率比较&#xff0c;线路图。 FP6298输入3.3V,输出9V,限流1A,效率88-90% FP6298 是一顆電流控制模式升壓轉換器&#xff0c;脈波寬度調變&#xff0c;內置 80mΩ, 4.5A, 12V MOSFET&#xff0c;能 做最…

最新版苹果手机html5摇一摇,iphone微信摇一摇失效问题解决

从ios12.2(具体版本可能有些许出入)开始&#xff0c;ios限制http地址的陀螺仪事件&#xff0c;必须https才可以&#xff0c;我们的站点必须是https才能正常生效&#xff0c;于是乎一大堆程序员吭哧吭哧的填好了坑。 当然虽然我们每天如履薄冰&#xff0c;战战兢兢&#xff0c;并…

iphone在微信中audio 音频无法自动播放

<audio src"1213132.mp3"controls"controls" preload id"music1" autoplay"autoplay" hidden></audio>js是这样的 function bf(){var audio document.getElementById(music1);if(audio!null){//检测播放是否已暂停.audio…

FS5175AE降压型1-4节锂电池充电芯片

FS5175AE是一款工作于5V到24V的多串锂电池同步开关降压充电管理芯片。内置MOS管集成了低导通阻抗的NMOS&#xff0c;FS5175AE采用1MHz同步开关架构&#xff0c;实现高 效率充电并简化外围器件&#xff0c;降低BOM成本。通过调节检测电阻&#xff0c;可实现**2A充电电流&#xf…