kakts-log

programming について調べたことを整理していきます

C socket accept時に accept: Socket operation on non-socket が出るときの対処法

最近、tcpソケットまわりの知識を身につけたいとおもい、
ネットワークプログラミングに関する技術書を購入して勉強をはじめました。

Linuxネットワークプログラミングバイブル

Linuxネットワークプログラミングバイブル

この本の内容を参考に、socketサーバをC言語で書いているのですが、socketのaccept時でエラーが出ていてかなりハマってしまった。

// accept loop
// 並列処理を行っていないので、受け付けた後、1つのクライアントの送受信処理が終わるまで他の受付ができない。
void accept_loop(int soc) {
  char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
  struct sockaddr_storage from;
  int acc;
  socklen_t len;


  for (;;) {
    len = (socklen_t) sizeof(from);

    // waiting connection
    // 1つも待ちがない状態だとaccept()実行でブロックする

    // ここでsocが0になっている
    acc = accept(soc, (struct sockaddr *) &from, &len);
    // 以下略...
    }
  }
}

クライアントからのソケット接続を待ち受ける箇所で accept()を呼んでいる箇所で
accept: Socket operation on non-socket
エラーが出ていてクライアントからのtelnetでのポート接続ができるがメッセージのやりとりができない状態となっていました。 エラーコードを確認すると38 になっていて、accept()の第1引数で渡すint socの値がソケットでない場合に起きるものです。

ENOTSOCK 38  ※Socket operation on non-socket   ソケットではない

socの値を確認してみると、soc が0になっていたので、socの値を代入している箇所をチェック。
代入箇所で細かいバグがあったので直したら解決した。

まとめ

ソケットサーバ起動時に accept: Socket operation on non-socket エラーが出たとき

accept*1の第1引数のsocketディスクリプタの値が異常値になっているため、 socketディスクリプタの作成*2に失敗している可能性がある