Unix域套接字数据报客户端,仅接收

时间:2020-02-05 09:29:14

标签: sockets unix dns

我有一个Unix域数据报套接字的模拟器应用程序,它将数据发送到for.ex / var / lib / XYZ的套接字路径。 sendto返回-2,这是由于另一端没有对等点(没有其他的unix domian套接字应用程序正在运行)

我想使用Unix域套接字编写一个数据报客户端/对等应用程序,以从服务器/模拟器(将数据发送到/ var / lib / XYZ)接收数据。

我的代码如下:

#define BUF_SIZE 1024

#define SV_SOCK_PATH "/var/lib/XYZ"
#define SV_SOCK_PATH2 "/var/lib/ABC"

创建Unix域套接字如下:

    struct sockaddr_un svaddr, claddr;
    ....      

    sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if (sfd == -1)
        printf("socket creation failed");

    memset(&claddr, 0, sizeof(struct sockaddr_un));
    claddr.sun_family = AF_UNIX;

    strncpy(claddr.sun_path, SV_SOCK_PATH2, sizeof(claddr.sun_path) - 1);

    if (bind(sfd, (struct sockaddr *) &claddr, sizeof(struct sockaddr_un)) == -1)
        printf("bind failed");

    /* 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);



    while(1)
    {
     int len=sizeof(struct sockaddr_un);
     numBytes = recvfrom(sfd, resp, BUF_SIZE, 0, (struct sockaddr*)&svaddr,&len);
     if (numBytes == -1)
            printf("recvfrom error");
        else{
        printf("no of bytes received from server: %d",(int)numBytes);
        printf("Response %d: %s\n", (int) numBytes, resp);
       }


    }


    remove(claddr.sun_path);            
    //exit(EXIT_SUCCESS);
}

但是程序没有接收到任何东西...有什么东西错过了吗?

1 个答案:

答案 0 :(得分:1)

当涉及到数据报时,没有真正的客户端或服务器。尝试发送的任何一方负责将数据报寻址到另一方。因此,在您的代码中,设置都是错误的。您显然正在尝试引导“服务器”(但实际上不是服务器,而只是另一个对等方)通过svaddr发送给您,但这不是它的工作方式。

对于数据报AF_UNIX套接字,发送者需要在sendto调用中显式指定接收者的地址,或者它需要首先将其套接字connect插入接收者的地址。 (在后一种情况下,由于通过send指定了对等地址,因此它可以使用sendto而不是connect。)

不能recvfrom呼叫中指定发送对等方的地址。 recvfrom中的套接字地址参数旨在返回给您发送数据报的地址。从recvfrom成功返回后,该变量中的任何内容都将被覆盖。

通常构造数据报对等程序的一种方式:“服务器”创建一个众所周知的路径并绑定到该路径,然后“客户端”创建其自己的终结点并绑定到它的 it (构造一个唯一的套接字地址),则客户端可以sendto服务器的知名套接字。服务器通过使用recvfrom来获得客户端的地址以及数据报,然后可以使用sendto以及地址来向客户端返回消息(无需connect的套接字) )。这在数据报套接字的基本对等方向之上提供了一种客户端-服务器范例。

最后,我应该提到,使用完全指定的路径名​​通常是一个好主意,以确保两个对等端都使用相同的地址,即使从不同的目录开始也是如此。 (通常,使用AF_UNIX时,该地址是文件系统中两个对等方之间“集合”的路径名-因此,如果没有完整路径,则在当前工作目录中,“ some_socket”为“ ./some_socket” 。某些系统(例如linux)还支持不需要完整路径的抽象“隐藏”名称空间,但您必须在名称中使用初始的空字节来指定该名称。)