0

何よりもまず、これを 'pselect' に関する質問としてタグ付けする評判がなかったので、'select' を使用しました。

UDP ソケットのタイムアウトを処理するために pselect を使用しています。コードは次のようになります。

UDP_STATUS udp_socket_recv(udp_socket_t* p_sock, int* p_bytes_rcvd)
{
    int res = 0;
    fd_set fds;
    struct timespec timeout;

    FD_ZERO(&fds);
    FD_SET(p_sock->m_socket, &fds);

    if (p_sock->m_timeout == NULL) {
        res = pselect(p_sock->m_socket + 1, &fds, NULL, NULL, NULL, NULL);
    } else {
        timeout.tv_sec = p_sock->m_timeout->tv_sec;
        timeout.tv_msec = p_sock->m_timeout->tv_usec * 1000;
        res = pselect(p_sock->m_socket + 1, &fds, NULL, NULL, &timeout, NULL);
    }

    if (res == 0)
        return UDP_TIMEOUT;
    else if (res == -1) {
        printf("pselect error: %s\n", strerror(errno)); /* Sometimes we end up here */
        return UDP_FAILURE;
    }

    res = recvfrom(p_sock->m_socket, ..); /* etc etc */
}

現在、上記は大部分のケースで問題なく機能します(ただし、コピー/貼り付けにアクセスできないため、何かをタイプミスした可能性があります)。ただし、pselect は -1 を返す場合があり、strerror(errno) 呼び出しで「中断されたシステム コール」が出力されます。

これがソケットタイムアウトをどのようにしたいのかさえわかりません。このソリューションをどのように思いついたのかさえ思い出せません...

どんな助けでも大歓迎です。

4

2 に答える 2

2

EINTR /中断されたシステムコールはエラー状態ではなく、プログラムがシステムコール内でブロックされている間に発生したものです(シグナルが配信され、処理された可能性があります)。これを無視して、次のように単純にループすることができます: (以下のプログラムは最適ではなく、EINTR の処理方法のデモンストレーションにすぎません)

UDP_STATUS udp_socket_recv(udp_socket_t* p_sock, int* p_bytes_rcvd)
{
int res = 0;
fd_set fds;
struct timespec timeout;

FD_ZERO(&fds);
FD_SET(p_sock->m_socket, &fds);

while(1) {
  if (p_sock->m_timeout == NULL) {
      res = pselect(p_sock->m_socket + 1, &fds, NULL, NULL, NULL, NULL);
  } else {
      timeout.tv_sec = p_sock->m_timeout->tv_sec;
      timeout.tv_msec = p_sock->m_timeout->tv_usec * 1000;
      res = pselect(p_sock->m_socket + 1, &fds, NULL, NULL, &timeout, NULL);
  }

  if (res > 0) break;
  if (res == 0)
    return UDP_TIMEOUT;

  switch(errno) {
  case EINTR: continue;
  default:
    printf("pselect error: %s\n", strerror(errno)); /* Sometimes we end up here */
    return UDP_FAILURE;
   }
 }

res = recvfrom(p_sock->m_socket, ..); /* etc etc */
}
于 2013-05-15T12:55:40.957 に答える