简体   繁体   English

如何使用SOCK_DGRAM制作双向unix域套接字?

[英]How to make two-directional unix domain sockets with SOCK_DGRAM?

I am trying to write a simple Unix datagram server/client, and am having some problems. 我正在尝试编写一个简单的Unix数据报服务器/客户端,并且遇到了一些问题。 What I want is a server that listens on a datagram socket and sends a reply to every message received, to the original sender. 我想要的是一个服务器,它监听数据报套接字并将收到的每条消息的回复发送给原始发送者。 I decided to try first using socat to be the "server" and writing the client in C. I am running socat like this: 我决定首先尝试使用socat作为“服务器”并在C中编写客户端。我正在运行这样的socat:

socat UNIX-DGRAM:/tmp/test.socket,fork EXEC:echo

To the best of my understanding this should listen on /tmp/test.socket and reply to everything that is received with the same string? 根据我的理解,这应该监听/tmp/test.socket并回复使用相同字符串收到的所有内容? Then I have a client program that looks like this (error checking removed for clarity): 然后我有一个看起来像这样的客户端程序(为清楚起见,删除了错误检查):

int s = socket(AF_UNIX, SOCK_DGRAM, 0);
struct sockaddr_un sa;
sa.sun_family = AF_UNIX;
strcpy(sa.sun_path, "/tmp/test.socket");

const char *data = "Testing data";
int err = sendto(s, data, strlen(data), 0, (struct sockaddr *)(&sa), sizeof(struct sockaddr_un));

printf("Sent!\n");

unsigned char *buffer = malloc(BUFFER_LENGTH);
struct sockaddr_storage recv_sa;
int recv_sa_len = 0;
int recv_len = recvfrom(s, buffer, BUFFER_LENGTH, 0, (struct sockaddr *)&recv_sa, &recv_sa_len);

for (int i = 0; i < recv_len; i++) {
    putc(buffer[i], stdout);
}
printf("\n");

It should send the packet (that works), receive a packet, and then print it out, but the program doesn't seem to be capable of receiving the packet. 它应该发送数据包(有效),接收数据包,然后将其打印出来,但程序似乎无法接收数据包。 What am I doing wrong here, or do I have a fundamental misunderstanding about Unix sockets? 我在这里做错了什么,或者我对Unix套接字有一个根本的误解? Thanks! 谢谢!

看看Michael Kerrisk的AF_UNIX SOCK_DGRAM客户端/服务器程序( 客户端服务器 )的示例,该示例发表在他的书“Linux编程接口”第57章中。

Socket need to have address to be addressed to receive packets. 套接字需要具有寻址以接收数据包的地址。 You can call bind() with unique socket filename based on the PID or in linux use autobound abstract address if to call before send : 您可以使用基于PID的唯一套接字文件名调用bind() ,或者在linux中使用autobound抽象地址,如果在send之前调用:

bind(s, (const struct sockaddr *)&sa, sizeof(sa_family_t));

You should call connect before of trying send nothing to the echo server. 您应该在尝试向echo服务器发送任何内容之前调用connect

Take a look at: http://beej.us/guide/bgipc/output/html/multipage/unixsock.html 请查看: http//beej.us/guide/bgipc/output/html/multipage/unixsock.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM