套接字,Unix域UDP C ++ recvfrom无法填充源地址

我试图在C ++上使用UDP在Android上创建一个unix域套接字服务器和客户端。 我需要客户端向服务器发送一条消息(“hi”),然后服务器上需要向客户端发送数据。 我已经成功创建了双方的套接字,并且能够从客户端接收服务器上的短消息。 但是,服务器上的recvfrom(..)不会填充struct sockaddr * src_addr和socklen_t * addrlen参数。 然后使用这些src_addr和addrlen的后续sendto消息显然失败(sendto返回-1)。

以下是服务器的代码:

int serverSocket = socket(PF_LOCAL, SOCK_DGRAM, 0);
int sendingBufferSize = OUTPUT_BUFFER_SIZE;
setsockopt(serverSocket, SOL_SOCKET, SO_SNDBUF, &sendingBufferSize, sizeof(sendingBufferSize));
struct sockaddr_un server;
memset(&server, 0, sizeof server);
server.sun_family = AF_LOCAL;

// the first byte of sun_path should be '' for abstract namespace
const char * socket_name = SOCKET_NAME;
server.sun_path[0] = '';
strcpy(server.sun_path + 1, socket_name);
socklen_t sockaddr_len = sizeof(server.sun_family) + strlen(socket_name) + 1;
if (bind(serverSocket, (struct sockaddr *) &server, sockaddr_len) < 0) {
    close(serverSocket);
    printf("Failed to bind the server socketn");
    return -1;
}

printf("- Socket binding successful on socket path %s len %dn", &server.sun_path[1], sockaddr_len);

_serverSocket = serverSocket;

后来我收到客户的一条消息:

int opcode;
_clientAddressLength = sizeof(struct sockaddr_un);
int numOfBytes = recvfrom(_serverSocket, _messageBuffer, INPUT_BUFFER, 0, (struct sockaddr *)&_clientAddress, &_clientAddressLength);
if (numOfBytes != 0)
{
    printf("Got a message from clientn");
    memcpy(&opcode, _messageBuffer, sizeof(opcode)); // I'm getting what I expected
}

但_clientAddress为空,_clientAddressLength设置为0。

然后

int result = sendto(_serverSocket
        , sendBuf
        , sendBufSize
        , 0
        , (const sockaddr*)&_clientAddress
        , _clientAddressLength);

返回-1

谢谢你们的帮助!

编辑:

最后感谢Nikolai N Fetissov的链接和一些挖掘工作。 我想通过UNIX DOMAIN抽象名称空间套接字发布一个固定的,100%双向UDP通信的工作示例。 这是一个带有固定错误的http://www.toptip.ca/2013/01/unix-domain-socket-with-abstract-socket.html?m=1链接的副本。 对于后代来说,因为在网络上没有足够的这个话题的例子。

server.cpp

#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h> 
#include <string.h>

#include <unistd.h>`

#define SERVER_SOCKET "#UdsServer" // The # is replaced by 0 for abstract namespace

int main(void)
{
int socket_fd;
struct sockaddr_un server_address, client_address; 
int bytes_received, bytes_sent, integer_buffer;
socklen_t address_length = sizeof(server_address.sun_family)+strlen(SERVER_SOCKET );

if ((socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
{
    perror("server: socket");
    return -1;
}

memset(&server_address, 0, sizeof(server_address));
server_address.sun_family = AF_UNIX;
memcpy(server_address.sun_path, SERVER_SOCKET,sizeof(SERVER_SOCKET)-1);// the path is not a C string, and is not NULL turminated
server_address.sun_path[0] = 0; 

if (bind(socket_fd,
         (const struct sockaddr *) &server_address,
         address_length) < 0)
{
    perror("server: bind");
    close(socket_fd);        
    return -1;
}

for (;;)
{
    bytes_received = recvfrom(socket_fd,
                              &integer_buffer,
                              sizeof(integer_buffer),
                              0, 
                              (struct sockaddr *) &client_address,
                              &address_length);

    if(bytes_received != sizeof(integer_buffer))
    {
        printf("Error: recvfrom - %d.n", bytes_received);
    } else {
        printf("received: %d.n", integer_buffer);

        integer_buffer += 10;

        bytes_sent = sendto(socket_fd,
                            &integer_buffer,
                            sizeof(integer_buffer),
                            0,
                            (struct sockaddr *) &client_address, 
                            address_length);
    }
}

close(socket_fd);

return 0;
}

client.cpp

#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define SERVER_SOCKET "#UdsServer" 
#define CLIENT_SOCKET "#UdsClient"
int main(void)
{
int socket_fd;
struct sockaddr_un server_address, client_address; 
int bytes_received, bytes_sent, integer_buffer;
socklen_t address_length = sizeof(server_address.sun_family) + strlen(CLIENT_SOCKET);`

if((socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
{
    perror("client: socket");
    return -1;
}

memset(&client_address, 0, sizeof(client_address));
client_address.sun_family = AF_UNIX;
memcpy(client_address.sun_path, CLIENT_SOCKET,sizeof(CLIENT_SOCKET )-1 );
client_address.sun_path[0] = 0;

if(bind(socket_fd,
        (const struct sockaddr *) &client_address, 
        address_length) < 0)
{
    perror("client: bind");
    return -1;
}

memset(&server_address, 0, sizeof(server_address));
server_address.sun_family = AF_UNIX;
memcpy(server_address.sun_path, SERVER_SOCKET,sizeof(SERVER_SOCKET)-1);
server_address.sun_path[0] = 0;

integer_buffer = 1;

for (;;)
{
   bytes_sent = sendto(socket_fd, 
                       &integer_buffer,
                       sizeof(integer_buffer),
                       0,
                       (struct sockaddr *) &server_address, 
                       address_length);

   bytes_received = recvfrom(socket_fd,
                             &integer_buffer,
                             sizeof(integer_buffer),
                             0, 
                             (struct sockaddr *) &server_address,
                             &address_length);

   if (bytes_received != sizeof(integer_buffer))
   {
       printf("Error: recvfrom - %d.n", bytes_received);
       return -1;
   }

   printf("received: %dn", integer_buffer);

   integer_buffer += 1;

   sleep(10);
}

close(socket_fd);

return 0;
}

我希望它有帮助,如果你看到更多的错误,请让我知道


您将地址大小参数设置为Internet地址sockaddr_in大小,对于Unix路径而言太小。

编辑0:

我相信问题是你没有bind(2)客户端套接字,所以它没有名称,因此recvfrom(2)返回地址长度为零。

从这里尝试代码(客户端需要一个与服务器名称不同的名称)。

链接地址: http://www.djcxy.com/p/61909.html

上一篇: Sockets, Unix Domain UDP C++ recvfrom fail to populate the source address

下一篇: endianness in ip header