我正在尝试使用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;
}
我的代码中缺少什么? connect和write函数返回0。
答案 0 :(得分:1)
我怀疑您的问题与您的write
:
err = write(sockfd, init, sizeof(init));
第二个参数应为&init
,仅传递init
将有效地展开结构,计算机将看到如下内容:
err = write(sockfd, init.en, init.pad, ..., sizeof(init));
由于write
只查看三个参数,因此它将使用init
个成员之一作为要写入的缓冲区的大小,该成员可能为零。实际的字节级参数堆栈取决于编译器和体系结构,因此您可以取笑我们自己,重要的是您没有提供write
您想要的内容。
你的编译器应该已经捕获了这个,如果没有,那么你需要提高警告选项的高度。
您可能希望逐个字节地构建发送到X服务器的数据,这样您就可以确保获得正确的字节顺序和偏移量。发送&init
会让您遇到常见问题(打包,对齐和字节顺序)的麻烦。