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

📄 closesock.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
字号:
/***********************************************************************//*                                                                     *//*   Module:  close.c                                                  *//*   Release: 2001.3                                                   *//*   Version: 99.0                                                     *//*   Purpose: closesocket() implementation                             *//*                                                                     *//*---------------------------------------------------------------------*//*                                                                     *//*               Copyright 1999, Blunk Microsystems                    *//*                      ALL RIGHTS RESERVED                            *//*                                                                     *//*   Licensees have the non-exclusive right to use, modify, or extract *//*   this computer program for software development at a single site.  *//*   This program may be resold or disseminated in executable format   *//*   only. The source code may not be redistributed or resold.         *//*                                                                     *//***********************************************************************/#include "../tcp_ipp.h"#include "../tcp/tcp.h"/***********************************************************************//* Symbol Definitions                                                  *//***********************************************************************/#define MAX_FIN_WAIT    (600 * TICKS_PER_SEC)/***********************************************************************//* Local Function Definitions                                          *//***********************************************************************//***********************************************************************//*   tcp_close: Close TCP socket                                       *//*                                                                     *//*       Input: sock = pointer to a TCP socket control block           *//*                                                                     *//*     Returns: 0 if no errors, else -1 with errno set to error code   *//*                                                                     *//***********************************************************************/static int tcp_close(SOCKET sock){  int rb_count = sock->rb_count;  /*-------------------------------------------------------------------*/  /* Free socket receive buffer, queued receive buffers, and OOS queue.*/  /*-------------------------------------------------------------------*/  TcpStrip(sock, FREE_RBUF);  /*-------------------------------------------------------------------*/  /* Only send FIN if ESTABLISHED, CLOSE_WAIT, or SYN_RCVD.            */  /*-------------------------------------------------------------------*/  switch (sock->state)  {    case SS_SYNRCVD:      /* send FIN */    case SS_ESTABLISHED:  /* send FIN */    case SS_FINWAIT1:    case SS_FINWAIT2:      /*---------------------------------------------------------------*/      /* Set maximum wait for peer's FIN.                              */      /*---------------------------------------------------------------*/      NetTimerStart(&sock->state_tmr, MAX_FIN_WAIT);      break;    case SS_CLOSING:    case SS_CLOSEWAIT:    /* send FIN */      /*---------------------------------------------------------------*/      /* Already received peer's FIN.                                  */      /*---------------------------------------------------------------*/      break;    default:      /*---------------------------------------------------------------*/      /* Connection already closed. Return success.                    */      /*---------------------------------------------------------------*/      return 0;  }  /*-------------------------------------------------------------------*/  /* Check if forceful close requested or received data remained.      */  /*-------------------------------------------------------------------*/  if ((sock->flags & SF_FORCEFUL) || rb_count)  {    sock->flags |= TCPF_RST;    TcpSendSeg(sock, 0);    TcpDrop(sock, ECONNABORTED);    return 0;  }  /*-------------------------------------------------------------------*/  /* Check if FIN needs to be sent.                                    */  /*-------------------------------------------------------------------*/  if ((sock->flags & SF_SND_SHUT) == FALSE)  {    /*-----------------------------------------------------------------*/    /* Record FIN request and its sequence number.                     */    /*-----------------------------------------------------------------*/    sock->flags |= SF_SNDFIN;    sock->fin_seq = sock->snt_una + sock->sb_count;    /*-----------------------------------------------------------------*/    /* Start output state machine.                                     */    /*-----------------------------------------------------------------*/    TcpTryOut(sock);    /*-----------------------------------------------------------------*/    /* Update state to either FIN_WAIT_1 or LAST_ACK.                  */    /*-----------------------------------------------------------------*/    if ((sock->state == SS_CLOSEWAIT) || (sock->flags & SF_OOOFIN))      sock->state = SS_LASTACK;    else /* state == ESTABLISHED or SYN_RCVD */      sock->state = SS_FINWAIT1;  }  /*-------------------------------------------------------------------*/  /* Check if socket has been configured to linger on closesocket().   */  /*-------------------------------------------------------------------*/  if (sock->flags & SF_LINGER)  {    /*-----------------------------------------------------------------*/    /* If non-blocking, report error and return -1.                    */    /*-----------------------------------------------------------------*/    if (sock->flags & SF_NONBLKNG)    {      NetError(NULL, EWOULDBLOCK);      return -1;    }    /*-----------------------------------------------------------------*/    /* Else wait for "closed" event and check for timeout.             */    /*-----------------------------------------------------------------*/    else    {      NetPendEvent(sock, SE_CLOSED, WAIT_FOREVER);      if (sock->error)      {        NetError(NULL, sock->error);        return -1;      }    }  }  /*-------------------------------------------------------------------*/  /* Return 0 for success.                                             */  /*-------------------------------------------------------------------*/  return 0;}/***********************************************************************//* Global Function Definitions                                         *//***********************************************************************//***********************************************************************//* closesocket: Public API for closing TCP or UDP socket               *//*                                                                     *//*       Input: s = socket identifier                                  *//*                                                                     *//*     Returns: 0 if no errors, else -1 with errno set to error code   *//*                                                                     *//***********************************************************************/int closesocket(int s){  SOCKET sock = &Socks[s - 1];  int rc = 0;#if OS_PARM_CHECK  /*-------------------------------------------------------------------*/  /* Verify protocol has been initialized.                             */  /*-------------------------------------------------------------------*/  if (!Net.Initialized)  {    NetError(NULL, ENETDOWN);    return -1;  }  /*-------------------------------------------------------------------*/  /* Check for valid socket ID.                                        */  /*-------------------------------------------------------------------*/  if (InvalidHandle(s))  {    NetError(NULL, ENOTSOCK);    return -1;  }#endif  /*-------------------------------------------------------------------*/  /* Acquire exclusive access to stack internals.                      */  /*-------------------------------------------------------------------*/  semPend(Net.IntSem, WAIT_FOREVER);  /*-------------------------------------------------------------------*/  /* Return error if socket is in process of being closed.             */  /*-------------------------------------------------------------------*/  if (sock->error == ENOTSOCK)  {    NetError(NULL, ENOTSOCK);    return -1;  }  /*-------------------------------------------------------------------*/  /* Record that socket is being closed.                               */  /*-------------------------------------------------------------------*/  sock->error = ENOTSOCK;  /*-------------------------------------------------------------------*/  /* Free any tasks blocked on this socket.                            */  /*-------------------------------------------------------------------*/  if (sock->events || sock->sel_evnts)    NetPostEvent(sock, SE_ERROR);  /*-------------------------------------------------------------------*/  /* Release exclusive access to internals and wait for API access.    */  /*-------------------------------------------------------------------*/  semPost(Net.IntSem);  if (semPend(sock->api_access, WAIT_FOREVER))  {    NetError(NULL, ENOTSOCK);    return -1;  }  /*-------------------------------------------------------------------*/  /* Re-acquire exclusive access to stack internals.                   */  /*-------------------------------------------------------------------*/  semPend(Net.IntSem, WAIT_FOREVER);  /*-------------------------------------------------------------------*/  /* Delete the API access semaphore and clear its handle.             */  /*-------------------------------------------------------------------*/  semDelete(sock->api_access);  sock->api_access = (SEM)NULL;  /*-------------------------------------------------------------------*/  /* If UDP socket, just post closed event.                            */  /*-------------------------------------------------------------------*/  if (sock->type == SOCK_DGRAM)    NetPostEvent(sock, SE_CLOSED);  /*-------------------------------------------------------------------*/  /* Else initiate TCP close.                                          */  /*-------------------------------------------------------------------*/  else    rc = tcp_close(sock);  /*-------------------------------------------------------------------*/  /* Release socket hold and internal access semaphore. Return status. */  /*-------------------------------------------------------------------*/  SockRelease(sock);  semPost(Net.IntSem);  return rc;}

⌨️ 快捷键说明

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