在这个最小示例程序中读取发送 unix 数据报域套接字的地址时,我得到的地址长度为 0,但 unix 域套接字的手册页指定:
unnamed:未使用 bind(2) 绑定到路径名的流套接字没有名称。同样,由 socketpair(2) 创建的两个套接字是未命名的。返回未命名套接字的地址时,其长度为 sizeof(sa_family_t),不应检查 sun_path。
根据此手册页,我期望未命名套接字的地址长度为 2。我是否误解了手册页,手册页是否不适用于 unix 类型的套接字,SOCK_DGRAM或者我只是错误地读取了长度?
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
const char SOCK_NAME[] = { 0, 't', 'e', 's', 't' };
// or for pathnamed socket
// const char SOCK_NAME[] = "/tmp/test.uds";
const char PAYLOAD[] = "Hello!";
int main() {
int rx_sock = socket(AF_UNIX, SOCK_DGRAM, 0);
if (rx_sock < 0) {
perror("Create RX");
exit(1);
}
int tx_sock = socket(AF_UNIX, SOCK_DGRAM, 0);
if (tx_sock < 0) {
perror("Create TX");
exit(1);
}
struct sockaddr_un bind_addr;
bind_addr.sun_family = AF_UNIX;
memcpy(bind_addr.sun_path, SOCK_NAME, sizeof(SOCK_NAME));
socklen_t bind_len = sizeof(sa_family_t) + sizeof(SOCK_NAME);
if (bind(rx_sock, (const struct sockaddr *)&bind_addr, bind_len) != 0) {
perror("Bind RX");
exit(1);
}
if (sendto(tx_sock, PAYLOAD, sizeof(PAYLOAD), 0, (const struct sockaddr *)&bind_addr, bind_len) < 0) {
perror("Sendto");
exit(1);
}
// For pathnamed socket
// unlink(SOCK_NAME);
struct sockaddr_un recv_addr;
socklen_t recv_len = sizeof(recv_addr);
char buffer[1024];
ssize_t rx_count = recvfrom(rx_sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&recv_addr, &recv_len);
if (rx_count < 0) {
perror("Recvfrom");
exit(1);
}
printf("Address size of TX on receiver side: %d\n", recv_len); // 0
recv_len = sizeof(recv_addr);
if (getsockname(tx_sock, (struct sockaddr *)&recv_addr, &recv_len) != 0) {
perror("getsockname");
exit(1);
}
printf("Address size of TX on sender side: %d\n", recv_len); // 2
}