⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sockopt.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
  /*-------------------------------------------------------------------*/  if (!Net.Initialized)  {    NetError(NULL, ENETDOWN);    return -1;  }  /*-------------------------------------------------------------------*/  /* Check for valid socket ID.                                        */  /*-------------------------------------------------------------------*/  if (InvalidHandle(s))  {    NetError(NULL, ENOTSOCK);    return -1;  }  /*-------------------------------------------------------------------*/  /* Check that the option is accessible and its length is correct.    */  /*-------------------------------------------------------------------*/  if (((optname != SO_CALLBACK) && (oval == NULL)) ||      ((optname == SO_LINGER) && (olen != sizeof(struct linger))) ||      ((optname != SO_LINGER) && (olen != sizeof(int))))  {    NetError(sock, EFAULT);    return -1;  }  /*-------------------------------------------------------------------*/  /* Verify protocol level and option name consistency                 */  /*-------------------------------------------------------------------*/  if (level == IPPROTO_TCP)  {    if (optname != TCP_NODELAY)    {      NetError(sock, ENOPROTOOPT);      return -1;    }  }  else if (level != SOL_SOCKET)  {    NetError(sock, ENOPROTOOPT);    return -1;  }#endif  /*-------------------------------------------------------------------*/  /* Gain exclusive socket API and stack internals access.             */  /*-------------------------------------------------------------------*/  if (semPend(sock->api_access, WAIT_FOREVER))  {    NetError(NULL, ENOTSOCK);    return -1;  }  semPend(Net.IntSem, WAIT_FOREVER);  /*-------------------------------------------------------------------*/  /* Determine which option is requested.                              */  /*-------------------------------------------------------------------*/  switch (optname)  {    case SO_BROADCAST:      /*---------------------------------------------------------------*/      /* Verify that socket type is UDP.                               */      /*---------------------------------------------------------------*/      if (sock->type != SOCK_DGRAM)      {        rc = -1;        NetError(sock, EOPNOTSUPP);        break;      }      /*---------------------------------------------------------------*/      /* Set UDP broadcast option.                                     */      /*---------------------------------------------------------------*/      if (*(int *)oval)        sock->flags |= SF_BROADCAST;      else        sock->flags &= ~SF_BROADCAST;      break;    case SO_NOCHECKSUM:      /*---------------------------------------------------------------*/      /* Verify that socket type is UDP.                               */      /*---------------------------------------------------------------*/      if (sock->type != SOCK_DGRAM)      {        rc = -1;        NetError(sock, EOPNOTSUPP);        break;      }      /*---------------------------------------------------------------*/      /* Set UDP checksum option.                                      */      /*---------------------------------------------------------------*/      if (*(int *)oval)        sock->flags |= SF_NOCHECKSUM;      else        sock->flags &= ~SF_NOCHECKSUM;      break;    case SO_CALLBACK:    {      sock->report = *(void (*)(int socket, ui32 events))oval;      break;    }    case SO_CONTIMEO:    {      int timeo = *(int *)oval;      /*---------------------------------------------------------------*/      /* Determine connect() timeout setting with 75 sec minimum.      */      /*---------------------------------------------------------------*/      if (timeo < 75000)        timeo = 75000;      sock->connect_timeo = Ms2Ticks(timeo);      break;    }    case SO_TOS:      /*---------------------------------------------------------------*/      /* Assign the type of service setting.                           */      /*---------------------------------------------------------------*/      sock->ip_tos = *(int *)oval;      break;    case SO_DONTROUTE:      /*---------------------------------------------------------------*/      /* Set dont-route option.                                        */      /*---------------------------------------------------------------*/      if (*(int *)oval)        sock->flags |= SF_DONTROUTE;      else        sock->flags &= ~SF_DONTROUTE;      break;    case SO_KEEPALIVE:      /*---------------------------------------------------------------*/      /* Verify that socket type is TCP.                               */      /*---------------------------------------------------------------*/      if (sock->type != SOCK_STREAM)      {        rc = -1;        NetError(sock, EOPNOTSUPP);        break;      }      /*---------------------------------------------------------------*/      /* Verify that socket is connected.                              */      /*---------------------------------------------------------------*/      if ((sock->flags & SF_CONNECTED) == FALSE)      {        rc = -1;        NetError(sock, ENOTCONN);        break;      }      /*---------------------------------------------------------------*/      /* Set keep-alive option.                                        */      /*---------------------------------------------------------------*/      if (*(int *)oval)        sock->flags |= SF_KEEPALIVE;      else      {        sock->flags &= ~SF_KEEPALIVE;        if (sock->state == SS_ESTABLISHED)          NetTimerStop(&sock->state_tmr);      }      break;    case SO_LINGER:    {      struct linger *lp = oval;      /*---------------------------------------------------------------*/      /* Verify that socket type is TCP.                               */      /*---------------------------------------------------------------*/      if (sock->type != SOCK_STREAM)      {        rc = -1;        NetError(sock, EOPNOTSUPP);        break;      }      /*---------------------------------------------------------------*/      /* If requested, disable linger on close and forceful close.     */      /*---------------------------------------------------------------*/      if (lp->l_onoff == FALSE)      {        sock->flags &= ~(SF_LINGER | SF_FORCEFUL);      }      /*---------------------------------------------------------------*/      /* Else enable linger and determine forceful close setting.      */      /*---------------------------------------------------------------*/      else      {        sock->flags |= SF_LINGER;        if (lp->l_linger)          sock->flags &= ~SF_FORCEFUL;        else          sock->flags |=  SF_FORCEFUL;      }      break;    }    case SO_OOBINLINE:      /*---------------------------------------------------------------*/      /* Verify that socket type is TCP.                               */      /*---------------------------------------------------------------*/      if (sock->type != SOCK_STREAM)      {        rc = -1;        NetError(sock, EOPNOTSUPP);        break;      }      /*---------------------------------------------------------------*/      /* Determine OOB data left in-line setting.                      */      /*---------------------------------------------------------------*/      if (*(int *)oval)        sock->flags |= SF_INLINE;      else        sock->flags &= ~SF_INLINE;      break;    case SO_RCVBUF:      /*---------------------------------------------------------------*/      /* Verify that socket type is TCP.                               */      /*---------------------------------------------------------------*/      if (sock->type != SOCK_STREAM)      {        rc = -1;        NetError(sock, EOPNOTSUPP);        break;      }      break;    case SO_RCVTIMEO:    {      int timeo = *(int *)oval;      /*---------------------------------------------------------------*/      /* Determine receive() timeout setting with 500 ms minimum.      */      /*---------------------------------------------------------------*/      if (timeo < 500)        timeo = 500;      sock->recv_timeo = Ms2Ticks(timeo);      break;    }    case SO_REUSEADDR:      /*---------------------------------------------------------------*/      /* Determine local address re-use setting.                       */      /*---------------------------------------------------------------*/      if (*(int *)oval)        sock->flags |= SF_REUSEADDR;      else        sock->flags &= ~SF_REUSEADDR;      break;    case SO_SNDBUF:      /*---------------------------------------------------------------*/      /* Verify that socket type is TCP.                               */      /*---------------------------------------------------------------*/      if (sock->type != SOCK_STREAM)      {        rc = -1;        NetError(sock, EOPNOTSUPP);        break;      }      break;    case SO_SNDTIMEO:    {      int timeo = *(int *)oval;      /*---------------------------------------------------------------*/      /* Determine send() timeout setting with 500 ms minimum.         */      /*---------------------------------------------------------------*/      if (timeo < 500)        timeo = 500;      sock->send_timeo = Ms2Ticks(timeo);      break;    }    case TCP_NODELAY:      /*---------------------------------------------------------------*/      /* Verify that socket type is TCP.                               */      /*---------------------------------------------------------------*/      if (sock->type != SOCK_STREAM)      {        rc = -1;        NetError(sock, EOPNOTSUPP);        break;      }      /*---------------------------------------------------------------*/      /* Determine whether Nagle's algorithm is to be disabled.        */      /*---------------------------------------------------------------*/      if (*(int *)oval)        sock->flags |= SF_NODELAY;      else        sock->flags &= ~SF_NODELAY;      break;    default:      rc = -1;      NetError(sock, ENOPROTOOPT);      break;  }  /*-------------------------------------------------------------------*/  /* Release exclusive API and internals access.                       */  /*-------------------------------------------------------------------*/  semPost(sock->api_access);  semPost(Net.IntSem);  return rc;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -