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

2番目のパラメーターは次のよう&initになります。渡すinitと、効果的に構造が展開され、コンピューターには次のようなものが表示されます。

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

write3つの引数のみを調べるため、書き込むバッファーのサイズとしてメンバーの1つを使用し、initそのメンバーはおそらくゼロです。実際のバイトレベルの引数スタックはコンパイラとアーキテクチャに依存するため、自分自身をからかうことができます。重要なことは、必要なものを供給していないことですwrite

コンパイラはこれをキャッチしているはずですが、キャッチしなかった場合は、警告オプションを可能な限り高くする必要があります。

とにかく、Xサーバーに送信するデータをバイトごとに作成することをお勧めします。そうすれば、バイトの順序とオフセットを正しく取得できます。送信&initすると、通常の容疑者(パッキング、アラインメント、バイトオーダー)に問題が発生します。

于 2011-01-03T04:01:12.717 に答える