«Неверный аргумент» в sendto с UNIX доменным сокетом дейтаграммы - PullRequest
0 голосов
/ 04 мая 2020

Следующие C программы создают сокет-сервер и клиентский сервер, а также функции для отправки и извлечения из сокета дейтаграммы домена UNIX, чтобы отправлять сообщения из нескольких потоков на клиенте, отправлять в один поток-получатель на стороне сервера.

Конечные точки клиента и сервера создаются без ошибок, но когда я вызываю client_send, я получаю «неверный аргумент», и функция завершается ошибкой.

Я опубликовал более ранний вопрос по этой (UNIX дейтаграмме домена - «Неверный аргумент» в sendto ) и в одном полезном ответе сказал, что он подозревает, что const struct sockaddr * svaddr неверна. Однако подпись client_send происходит непосредственно из Linux справочных страниц (https://linux.die.net/man/2/sendto):

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

Соответственно, мой вызов отражает подпись со справочной страницы Linux :

ssize_t result = sendto(sfd, buf, msgLen, 0, (struct sockaddr *) &svaddr, sizeof(struct sockaddr_un));

В качестве теста я попытался изменить указатель svaddr на вызов, чтобы исключить приведение:

ssize_t result = sendto(sfd, buf, msgLen, 0, svaddr, sizeof(struct sockaddr_un));

Но я получаю то же сообщение об ошибке "Недопустимый аргумент".

Вот код C:

#include <sys/un.h>
#include <sys/socket.h>
#include <ctype.h>
#include "tlpi_hdr_sockets.h"
#include "ud_ucase_sockets.h"
#include "error_functions_sockets.h"
#include "get_num_sockets.h"
#include "errno.h"

#define BUF_SIZE 750 /* Max size of messages between client to server */
#define SV_SOCK_PATH "/tmp/ud_ucase"

int64_t * create_socket_server(int64_t retvals[])
{
    struct sockaddr_un svaddr, claddr;
    int sfd, j;
    ssize_t numBytes;
    socklen_t len;
    char buf[BUF_SIZE];

    retvals[0] = 0;
    retvals[1] = 0;

    sfd = socket(AF_UNIX, SOCK_DGRAM, 0); /* Create server socket */

    if (sfd == -1)
         return retvals;

    /* Construct well-known address and bind server socket to it */

    if (remove(SV_SOCK_PATH) == -1 && errno != ENOENT)
           return retvals;

    memset(&svaddr, 0, sizeof(struct sockaddr_un));
    svaddr.sun_family = AF_UNIX;
    strncpy(svaddr.sun_path, SV_SOCK_PATH, sizeof(svaddr.sun_path) - 1);

    if (bind(sfd, (struct sockaddr *) &svaddr, sizeof(struct sockaddr_un)) == -1)
        return retvals;

    retvals[0] = sfd;
    retvals[1] = (int64_t)&svaddr;

     return retvals;
}

int64_t * create_socket_client(int64_t retvals[])
{
    struct sockaddr_un claddr;
    int sfd, j;
    size_t msgLen;
    ssize_t numBytes;
    char resp[BUF_SIZE];

    retvals[0] = 0;
    retvals[1] = 0;

    /* Create client socket; bind to unique pathname (based on PID) */

    sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if (sfd == -1)
        return retvals;

    memset(&claddr, 0, sizeof(struct sockaddr_un));
    claddr.sun_family = AF_UNIX;
    snprintf(claddr.sun_path, sizeof(claddr.sun_path), "/tmp/ud_ucase_cl.%ld", (long) getpid());

    retvals[0] = sfd;
    retvals[1] = (int64_t)&claddr;

     return retvals;
}

ssize_t client_send(int sfd, const void * buf, size_t msgLen, const struct sockaddr * svaddr)
{
    ssize_t result = sendto(sfd, buf, msgLen, 0, svaddr, sizeof(struct sockaddr_un));

     perror("socket");

    if (result != msgLen)
        return 0;

    return result;
}

int64_t server_receive(int64_t sfd, void * buf, int64_t msgLen, const void * claddr)
{
    socklen_t * len = (socklen_t * ) sizeof(struct sockaddr_un);
    int numBytes = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) claddr, len);

    if (numBytes == -1)
    return 0;

    return numBytes;
}

int close_socket(socket_fd)
{
    int closed = close(socket_fd);
    return closed;
}

Программы C вызываются из NASM, где параметры в заголовке функции C передаются в rdi, rsi, rdx и rcx:

; Open the socket client
lea rdi,[retvals_cli] ; a 2-element int64 array
call create_socket_client wrt ..plt
mov rdi,rax
mov rax,[rdi]
mov [socket_client_fd],rax
mov rax,[rdi+8]
mov [socket_client_addr],rax

; Open the Socket Server
lea rdi,[retvals_svr] ; a 2-element int64 array
call create_socket_server wrt ..plt
mov rdi,rax
mov rax,[rdi]
mov [socket_server_fd],rax
mov rax,[rdi+8]
mov [socket_server_addr],rax

; Client_send
mov edi,[socket_client_fd]
mov rsi,[rbp-24]
mov rdx,720
lea rcx,[socket_server_addr]
mov r8,r15
call client_send wrt ..plt

Недопустимый параметр в этой строке client_send:

    ssize_t result = sendto(sfd, buf, msgLen, 0, svaddr, sizeof(struct sockaddr_un));

Моя единственная проблема заключается в том, что после нескольких часов попыток разными способами передать параметры и вызвать его Я до сих пор не знаю, какой параметр неверен.

Спасибо за любую помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...