C/S架构学习之基于UDP的本地通信(客户机)

news/2024/5/18 15:29:35 标签: c语言, 架构, 学习, udp, linux, 服务器, 算法
  • 基于UDP的本地通信(客户机):
  • 创建流程:
  • 一、创建数据报式套接字(socket函数):
		int sock_fd = socket(AF_UNIX,SOCK_DGRAM,0);
	    if(-1 == sock_fd)
	    {
	        perror("socket error");
	        exit(-1);
	    }
  • 二、创建客户机和服务器的本地网络信息结构体并填充客户机和服务器本地网络信息结构体 (struct sockaddr_un):
  • 本地网络信息结构体:
	#include <sys/un.h>
	struct sockaddr_un {
	    sa_family_t sun_family;               //AF_UNIX
	    char        sun_path[108];            //pathname
	};
		struct sockaddr_un serveraddr,clientaddr;
	    socklen_t serveraddr_len = sizeof(serveraddr);
	    socklen_t clientaddr_len = sizeof(clientaddr);
	
	    memset(&serveraddr,0,serveraddr_len);
	    memset(&clientaddr,0,clientaddr_len);
	
	    serveraddr.sun_family = AF_UNIX;
	    clientaddr.sun_family = AF_UNIX;
	
	    strcpy(serveraddr.sun_path,"./udpserver");
	    strcpy(clientaddr.sun_path,"./udpclient");
  • 三、客户机绑定数据报式套接字(bind函数):
		if(-1 == bind(sock_fd,(struct sockaddr *)&clientaddr,clientaddr_len))
	    {
	        perror("bind error");
	        exit(-1);
	    }
  • 四、客户机端发收数据(sendto函数、recvfrom函数):
			memset(buf,0,sizeof(buf));
	
	        fgets(buf,sizeof(buf),stdin);
	        buf[strlen(buf) - 1] = '\0';
	        int ret1 = sendto(sock_fd,buf,sizeof(buf),0,(struct sockaddr *)&serveraddr,serveraddr_len);
	        if(-1 == ret1)
	        {
	            perror("sendto error");
	            exit(-1);
	        }
	
	        int ret2 = recvfrom(sock_fd,buf,sizeof(buf),0,(struct sockaddr*)&serveraddr,&serveraddr_len);
	        if(-1 == ret2)
	        {
	            perror("recvfrom error");
	            exit(-1);
	        }
	
	        printf("服务器[%s]发来应答消息[%s]\n",serveraddr.sun_path,buf);
  • 五、关闭套接字(close函数):
	close(sock_fd);
  • 示例代码:
	#include <stdio.h>
	#include <string.h>
	#include <stdlib.h>
	
	#include <sys/socket.h>
	#include <sys/types.h>
	
	#include <unistd.h>
	#include <stdbool.h>
	#include <sys/un.h>
	
	#include <arpa/inet.h>
	#include <netinet/ip.h>
	
	int main(int argc, char const *argv[])
	{
	    //创建套接字
	    int sock_fd = socket(AF_UNIX,SOCK_DGRAM,0);
	    if(-1 == sock_fd)
	    {
	        perror("socket error");
	        exit(-1);
	    }
	    //填充网络信息结构体
	
	    struct sockaddr_un serveraddr,clientaddr;
	    socklen_t serveraddr_len = sizeof(serveraddr);
	    socklen_t clientaddr_len = sizeof(clientaddr);
	
	    memset(&serveraddr,0,serveraddr_len);
	    memset(&clientaddr,0,clientaddr_len);
	
	    serveraddr.sun_family = AF_UNIX;
	    clientaddr.sun_family = AF_UNIX;
	
	    strcpy(serveraddr.sun_path,"./udpserver");
	    strcpy(clientaddr.sun_path,"./udpclient");
	
	
	    //绑定套接字
	    if(-1 == bind(sock_fd,(struct sockaddr *)&clientaddr,clientaddr_len))
	    {
	        perror("bind error");
	        exit(-1);
	    }
	
	    printf("基于UDP的本地通信客户机启动!!!\n");
	
	    char buf[128] = {0};
	    //收发数据
	    while(true)
	    {
	        memset(buf,0,sizeof(buf));
	
	        fgets(buf,sizeof(buf),stdin);
	        buf[strlen(buf) - 1] = '\0';
	        int ret1 = sendto(sock_fd,buf,sizeof(buf),0,(struct sockaddr *)&serveraddr,serveraddr_len);
	        if(-1 == ret1)
	        {
	            perror("sendto error");
	            exit(-1);
	        }
	
	        int ret2 = recvfrom(sock_fd,buf,sizeof(buf),0,(struct sockaddr*)&serveraddr,&serveraddr_len);
	        if(-1 == ret2)
	        {
	            perror("recvfrom error");
	            exit(-1);
	        }
	
	        printf("服务器[%s]发来应答消息[%s]\n",serveraddr.sun_path,buf);
	
	
	
	    }
	    //关闭套接字
	    close(sock_fd);
	
	    return 0;
	}



  • 运行结果:
	基于UDP的本地通信客户机启动!!!
	hello
	服务器[./udpserver]发来应答消息[hello---------k]
	I Love China!!!
	服务器[./udpserver]发来应答消息[I Love China!!!---------k]
	miss U
	服务器[./udpserver]发来应答消息[miss U---------k]

  • 特别注意:
  • strcpy(serveraddr.sun_path,"./udpserver");strcpy(clientaddr.sun_path,"./udpclient");代码段中的udpserver文件udpclient文件套接字文件
  • 如下所示:
	srwxrwxr-x 1 linux linux     0 1111 01:18 udpclient
	srwxrwxr-x 1 linux linux     0 1111 01:18 udpserver

http://www.niftyadmin.cn/n/5171469.html

相关文章

视频批量剪辑:视频合并技巧全攻略,成为视频剪辑专家

在视频制作的过程中&#xff0c;我们常常会遇到需要将多个视频片段合并的需求。这不仅涉及到视频的排列和组合&#xff0c;还需要考虑过渡效果、音频同步等因素。在视频制作过程中&#xff0c;视频批量剪辑是一个非常关键的环节。它可以大大提高工作效率&#xff0c;减少重复劳…

云栖大会丨桑文锋:打造云原生数字化客户经营引擎

近日&#xff0c;2023 云栖大会在杭州举办。今年云栖大会回归了 2015 的主题&#xff1a;「计算&#xff0c;为了无法计算的价值」。神策数据创始人 & CEO 桑文锋受邀出席「生态产品与伙伴赋能」技术主题&#xff0c;并以「打造云原生数字化客户经营引擎」为主题进行演讲。…

大数据-之LibrA数据库系统告警处理(ALM-12038 监控指标转储失败)

告警解释 用户在FusionInsight Manager界面配置监控指标转储后&#xff0c;转储失败时产生该告警。 转储成功后&#xff0c;告警恢复。 告警属性 告警ID 告警级别 可自动清除 12038 严重 是 告警参数 参数名称 参数含义 ServiceName 产生告警的服务名称。 RoleNa…

“两个Pizza“原则-高效技术团队的组建思考

两个Pizza原则是由亚马逊的贝佐斯提出的&#xff0c;并付诸实施的一个技术团队组建原则&#xff0c;即一个高效的技术研发团队&#xff0c;最佳的团队规模应该控制在2个pizza就可以吃饱的人数规模。一般建议在4到9个人&#xff0c;最佳在6个人。 业务的逐步扩大&#xff0c;研…

【技术支持】DevTools中重写覆盖源js文件

sources面板下&#xff0c;左侧overrides标签下添加一个文件夹&#xff0c;并同意。 勾选Enable Local overrides 然后在page标签下&#xff0c;修改文件后ctrls保存 直接就保存在overrides的文件夹下了 或者文件上右键Override content

计算消费总额

补充横线处的代码。dictMenu 中存放了你的双人下午套餐&#xff08;包括咖啡 2 份和点心 2 份&#xff09;的价格&#xff0c;计算并输出消费总额。‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬…

TDengine数据迁移之数据对比

数据完整性和一致性校验是迁移数据后的必要步骤&#xff0c;TDengine 数据迁移也是如此。但通常TDengine存储的都是海量数据&#xff0c;动辄几百亿条数据&#xff0c;如果像手工对比差异&#xff0c;工作量是非常巨大的。 以下脚本实现了对两个数据库记录数的对比。主要实现方…

ROS 学习应用篇(三)服务Server学习之Server

话题Topic是订阅器与发布器节点之间的&#xff0c;而服务则是客户端&#xff08;Client&#xff09;和服务器&#xff08;Server&#xff09;间的&#xff0c;前者是异步的&#xff0c;后者是同步的。而且话题是单项的不需要服务器上线&#xff0c;而服务是双向的。在开启服务之…