无法打印f客户端sun_path UNIX域套接字

问题描述

这里是我正在使用的UNix域服务器和客户端代码。服务器和客户端通过相互接收消息来相互发送消息。

服务器代码通过填充client_address从recvfrom向客户端发送消息。此外,如您所见,此unix域套接代码使用抽象命名系统。服务器名为UnixServer,客户端名为UnixClient。如果服务器可以通过填充其client_address向客户端发送消息,我想看看该地址是什么。我可以将其打印为#UdsClient等吗?

服务器代码

#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,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),(struct sockaddr *) &client_address,&address_length);

    

    struct sockaddr_storage ss;
    socklen_t sslen = sizeof(struct sockaddr_storage);
    if (getsockname(socket_fd,(struct sockaddr *)&ss,&sslen) == 0) {
           struct sockaddr_un *un = (struct sockaddr_un *)&ss;
           printf("socket name is: %s\n",un->sun_path);
    }

    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,address_length);

    //printf("clientaddress: %s",client_address.sa_data);
    }
}

close(socket_fd);

return 0;
}

客户代码

#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,integer_buffer;
socklen_t address_length = sizeof(server_address.sun_family) + strlen(CLIENT_SOCKET);

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

memset(&client_address,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,sizeof(SERVER_SOCKET)-1);
server_address.sun_path[0] = 0;

integer_buffer = 1;

for (;;)
{
   bytes_sent = sendto(socket_fd,(struct sockaddr *) &server_address,address_length);
      printf("clientaddress: %s",server_address.sun_path);

   bytes_received = recvfrom(socket_fd,&address_length);
     printf("clientaddress: %s",server_address.sun_path);

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

   printf("received: %d\n",integer_buffer);

   integer_buffer += 1;

   sleep(10);
}

close(socket_fd);

return 0;
}

此外,我尝试使用以下代码行将其打印出来,但它什么也不打印:

   struct sockaddr_storage ss;
    socklen_t sslen = sizeof(struct sockaddr_storage);
    if (getsockname(socket_fd,un->sun_path);
    } 

我在做错什么,如何打印#UdsClient或其他含义完整的东西?

编辑,我的解决方

我认为这是一个相对容易的问题。代替最后的代码,我可以如下读取它:

printf("socket name is: #%s\n",client_address.sun_path + 1);

因此该路径被填充,但是由于第一个字母为空,因此无法直接将其打印出来。

您还可以将这种方法用于非Abstract文件路径系统。

解决方法

当您将%s用作printf的格式说明符时,它将关联的参数视为以null结尾的char数组。但是,您可以通过设置...来使用抽象套接字。

server_address.sun_path[0] = 0;

因此,printf会将server_address.sun_path视为零长度的字符串-在 之后的前导空字符之后,它对数据一无所知。