Unix/Linux编程:UDS 数据报

news/2024/10/22 11:37:21/

〇、前言

对于recvfrom()来讲,src_addr 和 addrlen 参数会返回用来发送数据报的远程 socket 的地址。
(这些参数类似于 accept()中的 addr 和 addrlen 参数,它们返回已连接的对等 socket 的地址。) src_addr 参数是一个指针,它指向了一个与通信 domain 匹配的地址结构。与 accept()一样, addrlen 是一个值-结果参数。在调用之前应该将 addrlen 初始化为 src_addr 指向的结构的大小;在返回之后,它包含了实际写入这个结构的字节数。

一、接收:recvfrom()

在Socket编程中,recvfrom()函数用于从套接字接收数据,并获取发送方的地址信息。它适用于基于数据报的套接字,如UDP套接字。
recvfrom()函数的原型如下:

#include <sys/types.h>
#include <sys/socket.h>ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
  • sockfd:Socket文件描述符,表示要接收数据的套接字。
  • buf:指向接收数据的缓冲区的指针。
  • len:缓冲区的大小,表示最多接收多少字节的数据。
  • flags:标志参数,用于控制接收操作的行为,通常设置为0。
  • src_addr:指向struct sockaddr类型的指针,用于存储发送方的地址信息。
  • addrlen:指向socklen_t类型的指针,用于存储src_addr结构体的大小。

在调用recvfrom() 函数时,需要提供一个已经创建和绑定的套接字,并传递一个缓冲区以存储接收到的数据。函数将阻塞,直到有数据到达套接字。

当接收到数据时,recvfrom() 函数将数据存储在提供的缓冲区中,并将发送方的地址信息存储在src_addr中。实际接收的字节数将作为函数的返回值返回,如果返回值为-1,则表示发生了错误。

下面是一个简单的示例,演示如何使用recvfrom()函数接收UDP套接字的数据:

// us_xfr.h
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <zconf.h>#define BUF_SIZE 10 #define SV_SOCK_PATH "/tmp/ud_ucase"int main(int argc, char *argv[]) {struct sockaddr_un svaddr, claddr;int sfd, j;ssize_t numBytes;socklen_t len;char buf[BUF_SIZE];sfd = socket(AF_UNIX, SOCK_DGRAM, 0); /* Create server socket */if (sfd == -1) {perror("socket");exit(EXIT_FAILURE);}if (strlen(SV_SOCK_PATH) > sizeof(svaddr.sun_path) - 1) {printf("Server socket path too long: %s", SV_SOCK_PATH);exit(EXIT_FAILURE);}if (remove(SV_SOCK_PATH) == -1 && errno != ENOENT) {printf("remove-%s", SV_SOCK_PATH);exit(EXIT_FAILURE);}memset(&svaddr, 0, sizeof(struct sockaddr_un));svaddr.sun_family = AF_UNIX;strncpy(svaddr.sun_path, SV_SOCK_PATH, sizeof(svaddr.sun_path) - 1);if (bind(sfd, (struct sockaddr *)&svaddr, sizeof(struct sockaddr_un)) ==-1) {printf("bind");exit(EXIT_FAILURE);}/* Receive messages, convert to uppercase, and return to client */for (;;) {len = sizeof(struct sockaddr_un);numBytes =recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *)&claddr, &len);if (numBytes == -1) {printf("recvfrom");exit(EXIT_FAILURE);}printf("Server received %zd bytes from %s\n", numBytes,claddr.sun_path);for (j = 0; j < numBytes; j++)buf[j] = toupper((unsigned char)buf[j]);if (sendto(sfd, buf, numBytes, 0, (struct sockaddr *)&claddr, len) !=numBytes) {printf("sendto");exit(EXIT_FAILURE);}}
}

二、发送:sendto()

在Socket编程中,sendto() 函数用于通过套接字发送数据到指定的目标地址。它适用于基于数据报的套接字,如UDP套接字。
sendto() 函数的原型如下:

#include <sys/types.h>
#include <sys/socket.h>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:标志参数,用于控制发送操作的行为,通常设置为0。
  • dest_addr:指向struct sockaddr类型的目标地址结构体的指针,用于指定发送数据的目标地址。
  • addrlen:dest_addr结构体的大小。

下面是一个简单的示例,演示如何使用sendto() 函数发送UDP套接字的数据:

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <zconf.h>#define BUF_SIZE                                                               \10 /* Maximum size of messages exchanged between client and server */
#define SV_SOCK_PATH "/tmp/ud_ucase"
int main(int argc, char *argv[]) {struct sockaddr_un svaddr, claddr;int sfd, j;size_t msgLen;ssize_t numBytes;char resp[BUF_SIZE];if (argc < 2 || strcmp(argv[1], "--help") == 0) {printf("%s msg...\n", argv[0]);exit(1);}/* Create client socket; bind to unique pathname (based on PID) */sfd = socket(AF_UNIX, SOCK_DGRAM, 0);if (sfd == -1) {perror("socket");exit(EXIT_FAILURE);}memset(&claddr, 0, sizeof(struct sockaddr_un));claddr.sun_family = AF_UNIX;snprintf(claddr.sun_path, sizeof(claddr.sun_path), "/tmp/ud_ucase_cl.%ld",(long)getpid());if (bind(sfd, (struct sockaddr *)&claddr, sizeof(struct sockaddr_un)) ==-1) {perror("bind");exit(EXIT_FAILURE);}/* Construct address of server */memset(&svaddr, 0, sizeof(struct sockaddr_un));svaddr.sun_family = AF_UNIX;strncpy(svaddr.sun_path, SV_SOCK_PATH, sizeof(svaddr.sun_path) - 1);for (j = 1; j < argc; j++) {msgLen = strlen(argv[j]); if (sendto(sfd, argv[j], msgLen, 0, (struct sockaddr *)&svaddr,sizeof(struct sockaddr_un)) != msgLen) {perror("sendto");exit(EXIT_FAILURE);}numBytes = recvfrom(sfd, resp, BUF_SIZE, 0, NULL, NULL);if (numBytes == -1) {perror("recvfrom");exit(EXIT_FAILURE);}printf("Response %d: %.*s\n", j, (int)numBytes, resp);}remove(claddr.sun_path); exit(EXIT_SUCCESS);
}

三、运行

编译运行之后,启动客户端和服务端,键入:

(base) ***@shenjian Test % ./client_ud 你好 
hello nihao
Response 1: 你好
Response 2: HELLO
Response 3: NIHAO

可以在服务端看到:

Server received 6 bytes from /tmp/ud_ucase_cl.16568
Server received 5 bytes from /tmp/ud_ucase_cl.16568
Server received 5 bytes from /tmp/ud_ucase_cl.16568

可以看到运行结果符合预期。

全文完,感谢阅读。


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

相关文章

如何降低Epson XP打印机固件(修复墨水未识别错误)

介绍 尽管有一个最高法院裁决支持第三方墨水供应商&#xff0c;但打印机制造商仍在不遗余力地寻求消除更便宜的墨水替代品。从发布秘密固件更新伪装成安全补丁到eBay上可疑的移除通知&#xff0c;这些公司决心让消费者为高成本墨水付费。 对于Epson&#xff0c;默认情况下会应…

conda 环境安装 tensorflow2.0 tensorflow1.15

虚拟环境换台电脑就要装一次&#xff0c;在此记录一下吧&#xff0c;方便再次使用。 查看 tensorflow 和 python 对应版本可前往&#xff1a;在 Windows 环境中从源代码构建 | TensorFlow 这里简单展示一下 GPU 版本的&#xff1a; tensorflow2.0 & tensorflow1.15 这…

springboot mybatis-plus 代码生成工具

介绍 基于mybatis-plus代码生成工具 后续会不断完善 规划 后续会基于此功能搞低代码平台&#xff0c;会有前端VUE mybatis-plus介绍&特性 • 无侵入&#xff1a;只做增强不做改变&#xff0c;引入它不会对现有工程产生影响&#xff0c;如丝般顺滑 • 损耗小&#xff1…

【蓝桥杯算法题】字符串匹配算法

题目&#xff1a;用C语言写一个程序&#xff0c;输入一个字符串&#xff0c;过滤此串&#xff0c;只保留字符串中的字母字符&#xff0c;并统计新生成的字符串中包含的字母个数&#xff0c;要求用指针实现。 实现&#xff1a; #include <stdio.h> #include <ctype.h…

水滴屏壁纸来了!有你喜欢的吗?

高清原图下载地址在小程序宅哥工具箱哦&#xff01;

江南水乡

2004年夏天走访周庄,西塘等水乡, 相机是NiKon775 200万象&#xff0e;

梦中江南水乡

梦中江南水乡 最美是梦中江南水乡&#xff0c;乌篷船&#xff0c;青绿色的水&#xff0c;在江南烟雨中挺立千年的古木桥&#xff0c;斑驳的青石板路&#xff0c;木制的亭柱&#xff0c;红红的灯笼&#xff0c;两道砖墙间狭窄的路&#xff0c;说着轻柔的吴侬语走过后留下淡淡清…

简单家乡风景静态HTML网页设计作品 DIV布局家乡介绍网页模板代码-家乡佛山

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 家乡旅游景点 | 家乡民生变化 | 介绍自己的家乡 | 我的家乡 | 家乡主题 | HTML期末大学生网页设计作业 HTML&#xff1a;结构 CSS&#xff1a;样式 在…