简体   繁体   中英

Unix Datagram Socket works for first frame only

I'm attempting to do IPC with a UNIX data-gram socket but I'm having issues with the implementation. I was able to successfully do a UNIX stream socket but the functionality of my program mandates the use of data-grams.

Here is the code for the sending side:

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;

The receiving side will without fail get the first frame sent. However, the sendto function throws the "No such file or directory" error on this successful send. The following two sends produce the same error, but the sendto function returns (-1) instead of the correct buffer length like in the first call. In the subsequent calls to sendto the error becomes "Transort endpoint is not connected".

The receiving process is more complicated to copy/paste but essentially it first gets the file descriptor from the socket call, sets address structures, binds, and reads with recvfrom().

Here is a sample output log that may or may not be helpful:

Receiving Process Output

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

Sending Process Output

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

My questions are:

  1. If SOCK_DGRAM is connectionless and I'm using sendto(), why is it complaining about the transport endpoints?
  2. Why does this work for the first frame to be sent, but not others? Why does the successful frame still throw an error?
  3. How can I fix this?

You only initialize remote when out_sock == -1 . The second time you call the function remote will be uninitialized and so you get an error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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