0

我有两个通过 unix 域套接字(本地套接字)进行通信的守护进程(一个客户端和一个服务器)。我遇到的问题是服务器第一次使用recvfrom函数接收到数据报,然后recvfrom函数提供的客户端地址为空。但是,提供的客户地址的大小似乎是正确的。如果我增加客户端守护程序中的地址长度(更长的名称),这将反映在服务器地址大小的增加大小上。收到的数据也是正确的。

请注意,我只有在服务器第一次收到数据报时才会遇到这个问题。当收到其他数据报时,地址字段是正确的。

那里有任何专家了解可能出现的问题吗?

服务器代码:

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));
4

1 回答 1

0

我发现了我的错误。我应该在服务器代码中完成地址长度全局变量的初始化:

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

因为 address_length 是 recvfrom 函数的值结果参数。

于 2015-09-07T08:50:10.370 回答