senooken JP Social
  • FAQ
  • Login
senooken JP Socialはsenookenの専用分散SNSです。
  • Public

    • Public
    • Network
    • Groups
    • Popular
    • People

Conversation

Notices

  1. はいこん (hcm@mastodon.home.js4.in)'s status on Wednesday, 12-Sep-2018 01:11:11 JST はいこん はいこん

    “[socket] connectでのタイムアウト | Test better, code better” <https://moated.wordpress.com/2010/11/15/socket-connect%e3%81%a7%e3%81%ae%e3%82%bf%e3%82%a4%e3%83%a0%e3%82%a2%e3%82%a6%e3%83%88/>
    さっきと大体同じ内容だけどソース整形がされてるということで

    In conversation Wednesday, 12-Sep-2018 01:11:11 JST from mastodon.home.js4.in permalink

    Attachments

    1. No result found on File_thumbnail lookup.
      [socket] connectでのタイムアウト
      By FotoMasa from Test better, code better

      socketをconnectするときに、相手につながらないとconnectがエラー終了する。このときのエラーコードは、ETIMEOUTだ。perrorでのメッセージは Connection timed outだったり、Operation timed outになる。
      先日、non blockingに設定したsocketを使ってconnectするプログラムを書いていた。non blocking なので、connectは完了しなくても抜ける。これをselectで待って接続する、というのが本来やりたいことだった。

      テストのための小さいプログラムは以下のように書いた。
      細かいところは違っているが、だいたいこんな感じ。

      main()
      {
          int sock_id;
          struct in_addr inaddr;
          fd_set rfd,wfd;
          struct sockaddr_in dstaddr;
          int value;
          int n;
          int error;
          int len;
          sock_id = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
          if (sock_id &lt; 0) {
              perror(&quot;client socket&quot;);
              return;
          }
          value = 1;
          // non blocking socket
          if (ioctl(sock_id, FIONBIO, &amp;amp;value) &amp;lt; 0) {
              perror(&quot;client ioctl&quot;);
              close (sock_id);
          }
          inaddr.s_addr = htonl(0xc0a80082);
          dstaddr.sin_family      = AF_INET;
          dstaddr.sin_port        = htons(10080);
          dstaddr.sin_addr        = inaddr;
          if ((n = connect(sock_id,  (struct sockaddr *) &amp;amp;dstaddr,
          sizeof(struct sockaddr))) &lt; 0) {
          perror(&quot;connect&quot;);
          if (errno != EINPROGRESS)
              return;
          }
          if (n == 0)
          {
              printf(&quot;done\n&quot;);
              return;
          }
          // in progress
          FD_ZERO(&amp;amp;rfd);
          FD_ZERO(&amp;amp;wfd);
          FD_SET(sock_id, &amp;amp;wfd);
          if ((n =select(sock_id + 1, &amp;rfd, &amp;wfd, NULL, NULL)) &amp;lt; 0)
          {
              perror(&quot;select&quot;);
              return;
          }
          if (FD_ISSET(sock_id, &amp;amp;rfd) || FD_ISSET(sock_id, &amp;amp;wfd))
          {
              len = sizeof(error);
              if (getsockopt(sock_id, SOL_SOCKET, SO_ERROR, &amp;amp;error, &amp;amp;len) &amp;lt; 0)
              {
                   printf(&quot;getsockopt error&quot;);
                   return;
              }
          }
          else
          {
              printf(&quot;select error&quot;);
              return;
          }
          if (error)
          {
              close(sock_id);
              errno = error;
              perror(&quot;select return but:&quot;);
              return;
          }
      }
      

      selectにはタイムアウトを設定していないので、connectの作業が終了するまで抜けてこないだろうと思って書いていたところ、つながらないのに抜けてくることがある。
      timeoutのことを忘れていたことに気が付き、selectの後にgetsockoptでerror状態を取得して、エラーのときは接続エラーとして処理するように変更した。
      テストプログラムはエラーを検知するだけで終わっているが、実際のコードはエラーは除外して正常状態のsocketで通信を行う。
      FreeBSDのプロトコルスタックではconnectのタイムアウトは約75秒だ。
      この長さはOSごとに違っている。

    Feeds

    • Activity Streams
    • RSS 2.0
    • Atom
    • Help
    • About
    • FAQ
    • TOS
    • Privacy
    • Source
    • Version
    • Contact

    senooken JP Social is a social network, courtesy of senooken. It runs on GNU social, version 2.0.2-beta0, available under the GNU Affero General Public License.

    Creative Commons Attribution 3.0 All senooken JP Social content and data are available under the Creative Commons Attribution 3.0 license.