Unix数据报套接字仅适用于第一帧。

3
我正在尝试使用UNIX数据报套接字进行进程间通信,但是我在实现过程中遇到了问题。我成功地使用了UNIX流套接字,但我的程序功能要求使用数据报。

这是发送端的代码:

struct sockaddr_un remote;
struct sockaddr_un local;
socklen_t size_remote;
socklen_t size_local;
if(out_sock == -1)
{
    if ((out_sock = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
    {
        perror("toYYYYY socket");
        exit(1);
    }

    char remote_path[28] = "/tmp/sockets/fromXXXXXXX0000";
    sprintf(remote_path + 24, "%d", portOffset + XXXXXX_CTRL_UDP_PORT);
    memset(&remote, 0, sizeof(struct sockaddr_un));
    remote.sun_family = AF_UNIX;
    strcpy(remote.sun_path, remote_path);
    size_remote = (offsetof(struct sockaddr_un, sun_path) + strlen(remote_path));

    char local_path[28] = "/tmp/sockets/toYYYYY0000";
    sprintf(local_path + 20, "%d", portOffset + XXXXXX_CTRL_UDP_PORT);
    memset(&local, 0, sizeof(struct sockaddr_un));
    local.sun_family = AF_UNIX;
    strcpy(local.sun_path, local_path);
    size_local = (offsetof(struct sockaddr_un, sun_path) + strlen(local_path));

    unlink(local_path);
    int rtv = bind(out_sock, (struct sockaddr *)&local, size_local);
    if(rtv)
            perror("toYYYYY bind");

}
written = sendto(out_sock, packet, bytes, 0, (struct sockaddr *)&remote, size_remote);

if (written != bytes)
{
    status = AS_FAILURE;
    perror("toYYYYY send");
}

return status;

接收方将无论如何得到第一个发送的帧。然而,sendto函数在此成功发送时抛出“没有这样的文件或目录”错误。以下两个发送产生相同的错误,但sendto函数返回(-1),而不是像第一次调用中那样返回正确的缓冲区长度。在随后的sendto调用中,错误变为“传输端点未连接”。
接收过程更加复杂,不能直接复制/粘贴,但基本上它首先从套接字调用中获取文件描述符,设置地址结构,绑定,并使用recvfrom()读取。
以下是可能有助于的示例输出日志:
remote_len: 30
local_len: 26
local: '/tmp/sockets/toYYYYY5248' remote: '/tmp/sockets/fromXXXXXXX5248'
Binding to: '/tmp/sockets/fromXXXXXXX5248'
entered selected (This is receiving function with recvfrom())
recv from '/tmp/sockets/toYYYYY5248' len: 263
Closing socket

发送进程输出
send (successful call): Success
send: No such file or directory
send: No such file or directory
send: Transport endpoint is not connected
send: Transport endpoint is not connected
send: Transport endpoint is not connected
send: Transport endpoint is not connected
send: Transport endpoint is not connected
send: Transport endpoint is not connected
send: Transport endpoint is not connected
send: Transport endpoint is not connected

我的问题是:

  1. 如果SOCK_DGRAM是无连接的,我使用sendto(),为什么会抱怨传输端点?
  2. 为什么第一帧发送成功,但其他帧就不行了?为什么成功的帧仍然会报错?
  3. 我该如何修复这个问题?

1
在调用sendto之前尝试将errno设置为0,因为即使成功,sendto也不会清除errno。 - Drew McGowen
@DrewMcGowen 你说得对,改变 errno 后现在返回成功了。 - SBH
然而,我当然还有其他问题。 - SBH
问题可能是服务器在执行一次循环后消失了,导致错误消息完全准确。 - Jonathan Leffler
@DavidSchwartz 我展示给你的内容可能不太清楚,但是在所有这些失败的尝试之后,套接字会关闭。这只是进程结束时的行为。如果我将调试信息打印到同一流中,则套接字关闭是最后发生的。 - SBH
显示剩余3条评论
1个回答

1

只有在 out_sock == -1 时才会初始化 remote。第二次调用该函数时,remote 将未初始化,因此会出现错误。


1
哇,非常感谢。我知道会有人出现让我看起来很蠢 :) - SBH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接