Подключение к X-серверу

Я пытаюсь написать свою собственную программу, которая подключается к локальному X-серверу, который не использует Xlib или XCB, используя документацию по системному протоколу X Window. После записи данных соединения в сокет сервера я не могу прочитать ответ сервера, так как функциональные блоки чтения.

#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.


person kaykun    schedule 03.01.2011    source источник
comment
Можете ли вы подтвердить, что сервер (1) получил данные, которые вы ему отправили, и (2) отвечает данными, которые вы ожидаете получить в ответ?   -  person chrisaycock    schedule 03.01.2011
comment
Функция записи возвращает 0, поэтому я предполагаю, что можно предположить, что сервер получил данные, и сервер вообще не отвечает в соответствии с тем, что функция чтения не возвращается.   -  person kaykun    schedule 03.01.2011
comment
write возвращает количество записанных байтов, поэтому возврат нуля означает, что вообще ничего не было записано. Кроме того, возвращаемый тип write — это ssize_t, а не int, но это не ваша проблема.   -  person mu is too short    schedule 03.01.2011
comment
Моя глупая ошибка, функция записи изначально вернула -1, поэтому я мог спутать 0 с успехом.   -  person kaykun    schedule 03.01.2011


Ответы (1)


Я подозреваю, что ваша проблема связана с вашим write:

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

Второй параметр должен быть &init, передача только init фактически развернет структуру, и компьютер увидит что-то вроде этого:

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

Поскольку write рассматривает только три аргумента, он будет использовать один из элементов init в качестве размера буфера для записи, и этот элемент, вероятно, равен нулю. Фактический стек аргументов на уровне байтов зависит от компилятора и архитектуры, так что вы можете дразнить нас сами, важно то, что вы не передаете write то, что хотите.

Ваш компилятор должен был уловить это, если нет, то вам нужно максимально увеличить параметры предупреждения.

Вы, вероятно, захотите построить данные, которые вы отправляете на X-сервер, в любом случае, байт за байтом, таким образом, вы можете убедиться, что правильно получаете порядок байтов и смещения. Отправка &init вызовет у вас проблемы с обычными подозреваемыми (упаковка, выравнивание и порядок байтов).

person mu is too short    schedule 03.01.2011
comment
Спасибо, теперь я получаю хоть какой-то ответ, передавая &init. - person kaykun; 03.01.2011