0

我有兩個通過unix域套接字(本地套接字)進行通信的守護進程(一個客戶端和一個服務器)。我遇到的問題是,第一次在服務器中接收到數據報並使用recvfrom函數時,recvfrom函數提供的客戶端地址爲空。然而,提供的客戶地址的大小似乎是正確的。如果我增加客戶端守護進程中的地址長度(更長的名稱),這將反映在服務器地址大小的增加中。收到的數據也是正確的。沒有地址第一次運行雙向unix域套接字

請注意,我只有在服務器收到數據報時第一次遇到此問題。當接收到其他數據報時,地址字段是正確的。

那裏有任何專家瞭解什麼是錯的?

Server代碼:

static struct sockaddr_un myclient_address; 
socklen_t address_length = 0; 

int fd; 
struct sockaddr_un addr; 
struct my_device *dev = dev->device; 

fd = socket(AF_UNIX, SOCK_DGRAM, 0); 
if (fd < 0) { 
    f_warning("socket error"); 
} 

memset(&addr, 0, sizeof(addr)); 
addr.sun_family = AF_UNIX; 

memset(&myclient_address, 0, sizeof(myclient_address)); 
myclient_address.sun_family = AF_UNIX; 

char *socket_path = "#myserver"; 
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)); 
addr.sun_path[0] = '\0'; 

unlink(socket_path); 

if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { 
    f_warning("bind error"); 
} 

dev->socket_fd = fd; 
dev->socket_io_channel = g_io_channel_unix_new(fd); 
dev->socket_io_src_id = g_io_add_watch(dev->socket_io_channel, 
            G_IO_IN, 
            socket_in_data_callback, 
            dev); 

static gboolean 
socket_in_data_callback(GIOChannel *source, GIOCondition cond, gpointer  data) 
{ 
    struct my_device *dev = data; 
    gsize read_count = 0; 
    GIOStatus status; 
    guchar* data = g_malloc0(300); 
    read_count = recvfrom(dev->socket_fd, (char *) data, 300, 0, 
    (struct sockaddr *) &(myclient_address), &address_length); 
    return TRUE; 

}

客戶端代碼:

int fd; 

struct sockaddr_un mycli_addr; 

fd = socket(AF_UNIX, SOCK_DGRAM, 0); 
if (fd < 0) { 
    f_warning("socket error"); 
} 

memset(&addr, 0, sizeof(addr)); 
memset(&mycli_addr, 0, sizeof(mycli_addr)); 
addr.sun_family = AF_UNIX; 
mycli_addr.sun_family = AF_UNIX; 

char *socket_path = "#myserver"; 
char *mycli_socket_path = "#myclient"; 

strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)); 
strncpy(mycli_addr.sun_path, mycli_socket_path, sizeof(mycli_addr.sun_path)); 
addr.sun_path[0] = '\0'; 
mycli_addr.sun_path[0] = '\0'; 

unlink(socket_path); 
unlink(mycli_socket_path); 

int er; 
er = bind(fd, (struct sockaddr*)&mycli_addr, sizeof(mycli_addr)); 
if (er < 0) { 
    f_warning("bind error"); 
} 

if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { 
    f_warning("connect error"); 
} 

session->socket_io_channel = g_io_channel_unix_new(fd); 
session->socket_io_src_id = g_io_add_watch(session->socket_io_channel, 
              G_IO_IN, 
              client_socket_in_data_callback, 
              session); 

sendto(session->socket, (char *) mydata, data_length, 0, 
     (struct sockaddr *) &addr, 
     sizeof(struct sockaddr_un)); 

回答

0

我發現我的錯誤。我應該做的地址長度全局變量的這個初始化,然後在服務器代碼:

//socklen_t address_length = 0; 
socklen_t address_length = sizeof(myclient_address.sun_path); 

因爲ADDRESS_LENGTH是一個值結果參數recvfrom函數。