0

我正在尝试使用 X Window System Protocol 文档编写自己的程序,该程序连接到不使用 Xlib 或 XCB 的本地 X 服务器。将连接数据写入服务器套接字后,我似乎无法读回服务器的回复,因为读取功能阻塞。

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

int main()
{
  int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

  struct sockaddr_un serv_addr;
  memset((void*)&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sun_family = AF_UNIX;
  strcpy(serv_addr.sun_path, "/tmp/.X11-unix/X0");
  int servlen = 17 + sizeof(serv_addr.sun_family);

  int err = connect(sockfd, (struct sockaddr*)&serv_addr, servlen);

  printf("%d\n", err);

  struct
  {
    uint8_t en;
    uint8_t pad;
    uint16_t major;
    uint16_t minor;
    uint16_t name_len;
    uint16_t data_len;
    uint16_t pad2;
    uint8_t name[4];
    uint8_t data[4];
  } init;

  init.en = 'l';
  init.major = 11;
  init.minor = 0;
  init.name_len = 0;
  init.data_len = 0;

  err = write(sockfd, init, sizeof(init));

  printf("%d\n", err);

  uint8_t buf[5000];

  int n = read(sockfd, buf, 5000);

  return 0;
}

我的代码中缺少什么?连接和写入函数返回 0。

4

1 回答 1

1

我怀疑您的问题出在您的write

err = write(sockfd, init, sizeof(init));

第二个参数应该是&init,传递init将有效地展开结构,计算机将看到如下内容:

err = write(sockfd, init.en, init.pad, ..., sizeof(init));

由于write只查看三个参数,它将使用其中一个init成员作为要写入的缓冲区的大小,并且该成员可能为零。实际的字节级参数堆栈取决于编译器和体系结构,因此您可以自己取笑,重要的是您没有提供write您想要的东西。

你的编译器应该已经发现了这一点,如果没有,那么你需要将警告选项提高到尽可能高的程度。

无论如何,您可能希望逐字节构建发送到 X 服务器的数据,这样您可以确保获得正确的字节顺序和偏移量。发送&init会让你遇到常见的问题(打包、对齐和字节顺序)。

于 2011-01-03T04:01:12.717 回答