学习嵌入式第三十五天

文章目录

  • 网络(续上)
    • 1.函数接口
    • 2.相关功能实现
      • 1.TCP连接
      • 2.UDP
  • 习题

网络(续上)

1.函数接口

  • sendto

    原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
    功能:向一个指定的目标地址发送数据
    参数:sockfd:socket返回的套接字描述符buf:向包含要发送数据的缓冲区的指针len:要发送的数据长度flags:修改套接字调用行为的标志位,通常为0dest_addr:指向一个sockaddr结构体addrlen:指向的结构体的长度
    返回值:成功返回实际发送的字节数失败返回-1
    
  • recvfrom

    原型:ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
    功能:从套接字接收数据,并捕获发送数据方的源地址
    参数:sockfd:socket返回的套接字描述符buf:指向用于存放接收数据的缓冲区的指针len:缓冲区的最大长度flags:控制接受操作的标志位,通常为0src_addr:输出参数,一般为NULL,不为NULL时,函数将发送方的地址信息填充到这个结构体中addrlen:输入输出参数输入时:必须指向一个整数,大小为src_addr缓冲区的大小输出时:函数会修改这个整数,并将其设置为src_addr中实际存储的地址信息的真实长度
    返回值:成功返回接收到的字节数失败返回-1
    

2.相关功能实现

1.TCP连接

  • 客户端连接

    int tcp_client_connect(char const *ip,char const *port){int fd = socket(AF_INET,SOCK_STREAM,0);//创建一个TCP套接字if(fd < 0){perror("socket fail");return -1;}//创建失败struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));//初始化服务器地址结构体seraddr.sin_family = AF_INET;seraddr.sin_port = htons(atoi(port));//设置端口号seraddr.sin_addr.s_addr = inet_addr(ip);//输入自己的IP
    /*尝试连接到服务器,失败返回-1,成功返回套接字描述符*/if(connect(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("connect fail");return -1;}return fd;
    }
    
  • 服务器连接

    int tcp_accept(char const *ip,char const *port){int fd = socket(AF_INET,SOCK_STREAM,0);//创建一个TCP套接字if(fd < 0){perror("socket fail");return -1;}//创建失败res_fd[0] = fd;printf("fd = %d\n",fd);struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));//初始化服务器地址结构体seraddr.sin_family = AF_INET;seraddr.sin_port = htons(atoi(port));//设置端口seraddr.sin_addr.s_addr = inet_addr(ip);//设置IP
    /*绑定套接字到指定的IP和端口*/if(bind(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("connect fail");return -1;}
    /*监听端口,准备接受连接*/if(listen(fd,5) < 0){perror("listen fail");return -1;}
    /*接受一个客户端的连接,并返回连接的文件描述符*/int connfd = accept(fd,NULL,NULL);if(connfd < 0){perror("accept fail");return -1;}res_fd[1] = connfd;return connfd;
    }
    

2.UDP

  • 客户端向服务器端发送消息,服务器端回复收到

    • 客户端

      int main(){// 创建 UDP 套接字int clifd = socket(AF_INET,SOCK_DGRAM,0);if(clifd < 0){perror("socket fail"); // 创建失败,输出错误信息return -1;}// 定义并初始化服务器地址结构体struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET; // IPv4seraddr.sin_port = htons(50000); // 端口号50000,转为网络字节序seraddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器IP// 主循环,不断发送和接收消息while(1){char buf[1024] = {0}; // 发送缓冲区// 从标准输入读取一行数据fgets(buf,sizeof(buf),stdin);// 发送数据到服务器,包含字符串结束符int ret = sendto(clifd,buf,strlen(buf)+1,0,(const struct sockaddr*)&seraddr,sizeof(seraddr));char rbuf[1024] = {0}; // 接收缓冲区// 接收服务器返回的数据recvfrom(clifd,rbuf,sizeof(rbuf)+1,0,NULL,NULL);// 打印服务器返回的数据printf("buf = %s\n",rbuf);// 清空接收缓冲区memset(rbuf,0,sizeof(rbuf));}return 0;
      }
      
    • 服务器端

      int main(){// 创建 UDP 套接字int serfd = socket(AF_INET,SOCK_DGRAM,0);if(serfd < 0){perror("socket fail"); // 创建失败,输出错误信息return -1;}// 定义并初始化服务器地址结构体struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET; // IPv4seraddr.sin_port = htons(50000); // 端口号50000,转为网络字节序seraddr.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡// 绑定套接字和地址if(bind(serfd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("fail to bind"); // 绑定失败,输出错误信息return -1;}// 主循环,不断接收和回复客户端消息while(1){char buf[1024]; // 接收缓冲区struct sockaddr_in cliaddr; // 客户端地址结构体socklen_t len = sizeof(cliaddr); // 地址长度// 接收客户端消息,获取客户端地址int ret = recvfrom(serfd,buf,sizeof(buf),0,(struct sockaddr*)&cliaddr,&len);// 打印接收到的字节数printf("ret = %d \n",ret);printf("--------------------------\n");// 打印客户端IP地址printf("cliaddr = %s\n",inet_ntoa(cliaddr.sin_addr));// 打印客户端端口号printf("cliport = %d\n",ntohs(cliaddr.sin_port));printf("--------------------------\n");// 构造回复消息char sbuf[1024] = {0};sprintf(sbuf,"recv:%s",buf);// 发送回复消息给客户端sendto(serfd,sbuf,strlen(sbuf)+1,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr));// 清空发送缓冲区memset(sbuf,0,sizeof(sbuf));}return 0;
      }
      

习题

1.客户端向服务器端发送一个文件名,服务器将文件内容打包发给客户端

  • 客户端

    int main(){int clifd = socket(AF_INET,SOCK_DGRAM,0);if(clifd < 0){perror("socket fail");return -1;}struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");msg_t msg;msg.type = -1;fgets(msg.buf,sizeof(msg.buf),stdin);msg.buf[strlen(msg.buf)-1] = '\0';sendto(clifd,msg.buf,sizeof(msg.buf),0,(const struct sockaddr*)&seraddr,sizeof(seraddr));int fd = open(msg.buf,O_WRONLY|O_TRUNC|O_CREAT,0666);if(fd < 0){perror("fail to open file");return -1;}int n = 0;while((n = recvfrom(clifd,&msg,sizeof(msg),0,NULL,NULL)) > 0){if(msg.type == 0){break;}write(fd,msg.buf,msg.type);memset(&msg,0,sizeof(msg));}close(fd);
    close(clifd);
    return 0;
    }
    
  • 服务器端

    int main(){int serfd = socket(AF_INET,SOCK_DGRAM,0);if(serfd < 0){perror("socket fail");return -1;}struct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = INADDR_ANY;if(bind(serfd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("fail to bind");return -1;}DIR *dir;struct dirent *dp;msg_t msg;struct sockaddr_in cliaddr;socklen_t len = sizeof(cliaddr);dir = opendir("/home/linux/桌面");if(dir == NULL){perror("fail to open dir");return -1;}recvfrom(serfd,msg.buf,sizeof(msg.buf),0,(struct sockaddr*)&cliaddr,&len);printf("buf = %s\n",msg.buf);while(1){dp = readdir(dir);if(dp == NULL){perror("fail to read dir");return -1;}else if('.' == dp->d_name[0]){continue;}else if(strcmp(dp->d_name,msg.buf) == 0){sprintf(msg.buf,"/home/linux/桌面/%s",dp->d_name);int fd = open(msg.buf,O_RDONLY);if(fd < 0){perror("fail to open file");return -1;}int n;while((n = read(fd,msg.buf,sizeof(msg.buf))) > 0){msg.type = n;sendto(serfd,&msg,sizeof(msg),0,(const struct sockaddr*)&cliaddr,sizeof(cliaddr));}msg.type = 0;sendto(serfd,&msg,sizeof(msg),0,(const struct sockaddr*)&cliaddr,sizeof(cliaddr));close(fd);break;}}closedir(dir);
    close(serfd);
    return 0;
    }
    

2.用UDP实现服务器端和客户端的点对点聊天

  • 客户端

    int clifd;
    struct sockaddr_in seraddr;
    socklen_t len = sizeof(seraddr);void *thread1(void* arg){char buf[1024];while(1){memset(buf,0,sizeof(buf));recvfrom(clifd,buf,sizeof(buf),0,(struct sockaddr*)&seraddr,&len);if(strcmp(buf,".quit") == 0){printf("server quit\n");break;}printf("server say:%s\n",buf);}return NULL;
    }
    void *thread2(void* arg){char buf[1024];while(1){memset(buf,0,sizeof(buf));fgets(buf,sizeof(buf),stdin);if(strcmp(buf,".quit\n") == 0){break;}sendto(clifd,buf,strlen(buf)+1,0,(struct sockaddr*)&seraddr,sizeof(seraddr));}return NULL;
    }int main(){clifd = socket(AF_INET,SOCK_DGRAM,0);if(clifd < 0){perror("fail to socket");return -1;}memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");pthread_t pid1;pthread_t pid2;void *(*p1)(void*) = thread1;void *(*p2)(void*) = thread2;pthread_create(&pid1,NULL,p1,NULL);pthread_create(&pid2,NULL,p2,NULL);pthread_join(pid1,NULL);pthread_join(pid2,NULL);close(clifd);return 0;
    }
    
  • 服务器端

    int serfd;
    struct sockaddr_in seraddr;struct sockaddr_in cliaddr;
    socklen_t len = sizeof(cliaddr);void *thread1(void* arg){char buf[1024];while(1){memset(buf,0,sizeof(buf));recvfrom(serfd,buf,sizeof(buf),0,(struct sockaddr*)&cliaddr,&len);if(strcmp(buf,".quit") == 0){printf("client quit\n");break;}printf("client say:%s\n",buf);}return NULL;
    }
    void *thread2(void* arg){char buf[1024];while(1){memset(buf,0,sizeof(buf));fgets(buf,sizeof(buf),stdin);if(strcmp(buf,".quit\n") == 0){break;}sendto(serfd,buf,strlen(buf)+1,0,(struct sockaddr*)&cliaddr,len);}return NULL;
    }int main(){serfd = socket(AF_INET,SOCK_DGRAM,0);if(serfd < 0){perror("fail to socket");return -1;}memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = INADDR_ANY;if(bind(serfd,(const struct sockaddr*)&seraddr,sizeof(seraddr))< 0){perror("fail to bind");return -1;}pthread_t pid1;pthread_t pid2;void *(*p1)(void*) = thread1;void *(*p2)(void*) = thread2;pthread_create(&pid1,NULL,p1,NULL);pthread_create(&pid2,NULL,p2,NULL);pthread_join(pid1,NULL);pthread_join(pid2,NULL);close(serfd);return 0;
    }
    

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

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

相关文章

为什么给数据表加了索引,写入速度反而变慢了

为数据表增加索引后之所以会导致写入&#xff08;包括插入、更新、删除&#xff09;操作的速度变慢&#xff0c;其根本原因在于索引本质上是一个独立的、需要与主表数据保持实时同步的“数据结构”。这一机制的核心逻辑涵盖五个方面&#xff1a;因为索引本质上是一个“独立的数…

.NET Core 中采用独立数据库的SAAS(多租户)方法

介绍多租户是指一种软件架构&#xff0c;其中软件的单个实例在服务器上运行并为多个租户提供服务。在基于 SAAS 的平台中&#xff0c;租户是指使用该平台开展业务运营的客户。每个租户都拥有独立的数据、用户帐户和配置设置&#xff0c;并且与其他租户隔离。多租户允许有效利用…

运维日常工作100条

这是一份非常详细和实用的“运维日常工作100条”清单。它涵盖了从日常巡检、变更管理、故障处理到安全、优化和文档等运维工作的方方面面,可以作为运维工程师的日常工作指南和检查清单。 运维日常工作100条 一、日常巡检与监控 (20条) 检查核心监控大盘:查看整体业务健康状态…

OpenHarmony子系统介绍

OpenHarmony子系统OpenHarmony子系统1. AI业务子系统2. 方舟运行时子系统3. ArkUI框架子系统4. DFX子系统5. DeviceProfile子系统6. XTS子系统7. 上传下载子系统8. 主题框架子系统9. 事件通知子系统10. 位置服务子系统11. 元能力子系统12. 全局资源调度子系统13. 全球化子系统1…

博士招生 | 英国谢菲尔德大学 招收计算机博士

内容源自“图灵学术博研社”gongzhonghao学校简介谢菲尔德大学&#xff08;The University of Sheffield&#xff09;是英国久负盛名的公立研究型大学&#xff0c;也是罗素集团成员之一。在 2026 年 QS 世界大学排名中&#xff0c;谢菲尔德大学位列第92位&#xff0c;其中计算机…

如何理解面向过程和面向对象,举例说明一下?

面向过程和面向对象是两种不同的编程思想&#xff0c;核心区别在于解决问题的视角不同&#xff1a;前者关注 “步骤和过程”&#xff0c;后者关注 “对象和交互”。面向过程的核心思想是把问题拆解成一系列步骤&#xff0c;通过函数实现每个步骤&#xff0c;然后按顺序调用这些…

深入了解评估与微调中使用的Graders:原理、实现与最佳实践

深入了解评估与微调中使用的Graders 在模型评估与微调&#xff08;Fine-tuning&#xff09;过程中&#xff0c;Graders&#xff08;评分器&#xff09;是衡量模型输出与参考答案之间表现的重要工具。本文将系统介绍Grader的类型、技术实现及如何在实际项目中融入稳定且高质量的…

行缓存(line buffer)在图像卷积中的工作方式

上面这张图配合文字&#xff0c;展示了行缓存&#xff08;line buffer&#xff09;在图像卷积中的工作方式&#xff1a;上半部分是一个按行扫描输入的图像块&#xff08;示例为 99&#xff0c;编号 1–81&#xff09;。 蓝色表示已被写入行缓存并按队列等待的数据&#xff0c;绿…

【数据分享】中国371个城市的坡度矢量数据和excel数据

今天要说明数据就是中国371个城市的坡度矢量数据和excel数据。数据介绍在城市发展的进程中&#xff0c;地形地貌始终是影响规划决策的关键因素&#xff0c;而坡度作为表征地表倾斜程度的核心指标&#xff0c;更是贯穿于城市建设、生态保护等诸多环节。本文将全面解读中国 371 个…

《WINDOWS 环境下32位汇编语言程序设计》第7章 图形操作(1)

图形设备接口GDI&#xff08;Graphics Device Interface&#xff09;是Win32的一个重要组成部分&#xff0c;其作用是允许Windows的应用程序将图形输出到计算机屏幕、打印机或其他输出设备上。GDI实际上是一个函数库&#xff0c;包括直线、画图和字体处理等数百个函数。7.1 GDI…

数据结构-HashMap

在 Java 键值对&#xff08;Key-Value&#xff09;集合中&#xff0c;HashMap 是使用频率最高的实现类之一&#xff0c;凭借高效的查找、插入性能&#xff0c;成为日常开发的 “利器”。本文将从 HashMap 的底层原理、核心特点、常用方法到遍历方式、使用注意事项&#xff0c;进…

[系统架构设计师]安全架构设计理论与实践(十八)

[系统架构设计师]安全架构设计理论与实践&#xff08;十八&#xff09; 一.信息安全面临的威胁 1.信息系统安全威胁的来源 物理环境&#xff0c;通信链路&#xff0c;网络系统&#xff0c;操作系统&#xff0c;应用系统&#xff0c;管理系统 2.网络与信息安全风险类别 风险类别…

AI适老服务暖人心:AI适老机顶盒破数字鸿沟、毫米波雷达护独居安全,银发生活新保障

银发经济领域长期受限于 “专业照护资源稀缺”“老年人数字适应能力弱”“独居老人安全隐患多” 的困境&#xff0c;而 AI 技术的适老化改造&#xff0c;正让银发服务从 “被动保障” 转向 “主动关怀”&#xff0c;既能帮老年人跨越数字鸿沟&#xff0c;又能为独居老人筑起安全…

Linux应用软件编程---网络编程1(目的、网络协议、网络配置、UDP编程流程)

Linux下的网络编程一、目的不同主机&#xff0c;进程间通信。二、解决的问题1. 主机与主机之间物理层面必须互联互通。 2. 进程与进程在软件层面必须互联互通。物理层面的互联互通流程图如下&#xff1a;其中&#xff1a;IP地址&#xff1a;计算机的软件地址&#xff0c;用来标…

常见开源协议详解:哪些行为被允许?哪些被限制?

常见开源协议详解&#xff1a;哪些行为被允许&#xff1f;哪些被限制&#xff1f; 开源世界的魅力在于共享与合作&#xff0c;但不同的开源协议对分发、修改、再发布以及宣传/推广有不同的要求和限制。很多开发者在 fork 项目、改 README、放到自己仓库并在自媒体传播 时&…

服务器硬盘进行分区和挂载

查看服务器上的硬盘&#xff1a;lsblk -d -o NAME,SIZE,MODEL可以看到我的硬盘是除了vda系统盘以外&#xff0c;还有个vdb。我们查看一下分区&#xff1a;lsblk可以看到&#xff1a;vdb 1T disk &#xff08;底下没有分区&#xff0c;也没有挂载&#xff09;我们想要用起来这…

【C初阶】数据在内存中的存储

目录 1. 整数在内存中的存储 2. 大小端字节序 2.1 什么是大小端&#xff1f; 2.2 为什么有大小端&#xff1f; 2.3 练习 2.3.1 练习1 2.3.2 练习2 2.3.3 练习3 2.3.4 练习4 2.3.5 练习5 2.3.6 练习6 3. 浮点数在内存中的存储 3.1 浮点数存储的过程 3.2 浮点数的取…

AI 自动化编程 trae 体验2 帮我分析一个项目

总结&#xff1a; 接手一个项目可以让trae 帮忙分析 上次讲到trae在处理组件引入的时候&#xff0c;经常会碰到版本问题&#xff0c;分析引入了互联网上非本版本或者有bug的代码。主要依赖互联网的资源库。 但是分析一个项目应该是没问题。 这次表现非常好&#xff0c;接手一个…

VMware虚拟机中CentOS 7 报错 ping: www.xxx.com: Name or service not known

1:主要原因是网络配置的问题 2:其实就是下面三张图片中的,物理机虚拟网卡 vmware8 和虚拟机网络编辑器&#xff0c;如果设置静态IP 就是这三个地方的问题最简单的解决办法第一步&#xff1a;还原虚拟机网络点击确认后 ** 第二步给自己的虚拟机设置网络连接方式 选择NAT模式连接…

Java面试-自动装箱与拆箱机制解析

&#x1f44b; 欢迎阅读《Java面试200问》系列博客&#xff01; &#x1f680;大家好&#xff0c;我是Jinkxs&#xff0c;一名热爱Java、深耕技术一线的开发者。在准备和参与了数十场Java面试后&#xff0c;我深知面试不仅是对知识的考察&#xff0c;更是对理解深度与表达能力的…