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

📄 tcp_ip.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 4 页
字号:
/***********************************************************************/void SockRelease(SOCKET sock){  /*-------------------------------------------------------------------*/  /* Decrement socket reservation count and return if not zero.        */  /*-------------------------------------------------------------------*/  TcpAssert(sock->reserve_cnt > 0);  if (--sock->reserve_cnt)    return;  /*-------------------------------------------------------------------*/  /* Check if releasing a TCP socket.                                  */  /*-------------------------------------------------------------------*/  if (sock->type == SOCK_STREAM)  {    /*-----------------------------------------------------------------*/    /* Ensure socket is stripped of TCP resources.                     */    /*-----------------------------------------------------------------*/    TcpStrip(sock, FREE_RBUF | FREE_SBUF);    /*-----------------------------------------------------------------*/    /* Ensure all socket timers are stopped.                           */    /*-----------------------------------------------------------------*/    NetTimerStop(&sock->state_tmr);    NetTimerStop(&sock->out_tmr);    NetTimerStop(&sock->ack_tmr);  }  /*-------------------------------------------------------------------*/  /* Else free any datagrams queued on UDP socket.                     */  /*-------------------------------------------------------------------*/  else  {    while (sock->rq_head)    {      NetBuf *buf = sock->rq_head;      sock->rq_head = buf->next;      tcpRetBuf(&buf);    }  }  /*-------------------------------------------------------------------*/  /* Remove from respective TCP or UDP socket list.                    */  /*-------------------------------------------------------------------*/  sock->link.next_bck->next_fwd = sock->link.next_fwd;  sock->link.next_fwd->next_bck = sock->link.next_bck;  /*-------------------------------------------------------------------*/  /* If not deleted, delete API access semaphore.                      */  /*-------------------------------------------------------------------*/  if (sock->api_access)  {    semDelete(sock->api_access);    sock->api_access = NULL;  }  /*-------------------------------------------------------------------*/  /* Mark as "free" and place on end of free list.                     */  /*-------------------------------------------------------------------*/  sock->state = SS_FREE;  sock->link.next_fwd = NetSockList.next_fwd;  sock->link.next_bck = &NetSockList;  NetSockList.next_fwd->next_bck = &sock->link;  NetSockList.next_fwd = &sock->link;  ++Net.SockCount;}/***********************************************************************//*   SockAlloc: Allocate and initialize a new socket control block     *//*                                                                     *//*       Input: type = SOCK_DGRAM or SOCK_STREAM                       *//*                                                                     *//***********************************************************************/SOCKET SockAlloc(int type){  char name[9];  SOCKET sock = (SOCKET)NetSockList.next_bck;  SEM api_access;  /*-------------------------------------------------------------------*/  /* Return NULL if list of free sockets is empty.                     */  /*-------------------------------------------------------------------*/  if (NetSockList.next_bck == &NetSockList)    return NULL;  /*-------------------------------------------------------------------*/  /* Allocate API access semaphore.                                    */  /*-------------------------------------------------------------------*/  sprintf(name, "sa%u", (sock - &Socks[0]) + 1);  api_access = semCreate(name, 1, OS_FIFO);  if (api_access == NULL)    return NULL;  /*-------------------------------------------------------------------*/  /* Remove socket from free list and track low water mark.            */  /*-------------------------------------------------------------------*/  NetSockList.next_bck = NetSockList.next_bck->next_bck;  NetSockList.next_bck->next_fwd = &NetSockList;  if (--Net.SockCount < Net.SockMin)    Net.SockMin = Net.SockCount;  /*-------------------------------------------------------------------*/  /* Clear all uninitialized fields (required for UDP/TCPFreeSock()).  */  /*-------------------------------------------------------------------*/  memset(sock, 0, sizeof(struct socket));  /*-------------------------------------------------------------------*/  /* Add socket to appropriate protocol socket list.                   */  /*-------------------------------------------------------------------*/  if (type == SOCK_DGRAM)  {    sock->link.next_fwd = UdpLruList.next_fwd;    sock->link.next_bck = &UdpLruList;    UdpLruList.next_fwd->next_bck = &sock->link;    UdpLruList.next_fwd = &sock->link;  }  else  {    TcpAssert(type == SOCK_STREAM);    sock->link.next_fwd = TcpLruList.next_fwd;    sock->link.next_bck = &TcpLruList;    TcpLruList.next_fwd->next_bck = &sock->link;    TcpLruList.next_fwd = &sock->link;  }  /*-------------------------------------------------------------------*/  /* Initialize TCP/UDP common fields.                                 */  /*-------------------------------------------------------------------*/  sock->api_access = api_access;  sock->recv_timeo = sock->send_timeo = WAIT_FOREVER;  sock->connect_timeo = 75 * TICKS_PER_SEC;  sock->reserve_cnt = 1;  sock->state = SS_CLOSED;  sock->type = type;  /*-------------------------------------------------------------------*/  /* Return pointer to socket.                                         */  /*-------------------------------------------------------------------*/  return sock;}/***********************************************************************//*    NetError: Process TCP/IP errors                                  *//*                                                                     *//*      Inputs: sock = NULL or pointer to socket control block         *//*              err_code = API error code                              *//*                                                                     *//***********************************************************************/void NetError(SOCKET sock, int err_code){  /*-------------------------------------------------------------------*/  /* Set errno and, if handle provided, socket error code.             */  /*-------------------------------------------------------------------*/  errno = err_code;  if (sock)    sock->error = err_code;}/***********************************************************************//* NetPostEvent: Wake application task if waiting for posted event     *//*                                                                     *//*      Inputs: sock = pointer to socket control block                 *//*              events = bit mask for events being posted              *//*                                                                     *//***********************************************************************/void NetPostEvent(SOCKET sock, ui32 events){  /*-------------------------------------------------------------------*/  /* Wake application task waiting for events being posted.            */  /*-------------------------------------------------------------------*/  if (sock->events & events)  {    sock->events = 0;    taskWake(sock->taskid);  }  /*-------------------------------------------------------------------*/  /* Wake task blocked on select() if waiting for these events.        */  /*-------------------------------------------------------------------*/  if (sock->sel_id && (sock->sel_evnts & events))  {    sock->sel_evnts = 0;    taskWake(sock->sel_id);  }  /*-------------------------------------------------------------------*/  /* If installed, use callback function to report socket event.       */  /*-------------------------------------------------------------------*/  if (sock->report)    sock->report(sock - &Socks[0] + 1, events);}/***********************************************************************//* NetPendEvent: Wait for specified event with optional timeout        *//*                                                                     *//*      Inputs: sock = pointer to socket control block                 *//*              events = bit mask for events caller is waiting for     *//*              timeout = maximum number of ticks to wait              *//*                                                                     *//***********************************************************************/void NetPendEvent(SOCKET sock, ui32 events, ui32 timeout){  /*-------------------------------------------------------------------*/  /* Clear socket's error values.                                      */  /*-------------------------------------------------------------------*/  sock->soft_error = sock->error = 0;  /*-------------------------------------------------------------------*/  /* Save our task id and set the event bits we are pending for.       */  /*-------------------------------------------------------------------*/  sock->taskid = RunningTask;  sock->events = events;  /*-------------------------------------------------------------------*/  /* Prevent preemption between releasing internal access and sleeping.*/  /*-------------------------------------------------------------------*/  taskLock();  /*-------------------------------------------------------------------*/  /* Wait for event, releasing and re-acquiring internal access.       */  /*-------------------------------------------------------------------*/  semPost(Net.IntSem);  taskSleep(timeout);  semPend(Net.IntSem, WAIT_FOREVER);  /*-------------------------------------------------------------------*/  /* If events not received, we timed out. Set error value.            */  /*-------------------------------------------------------------------*/  if ((sock->events & events) == events)    sock->error = ETIMEDOUT;  /*-------------------------------------------------------------------*/  /* Clear bits from event mask.                                       */  /*-------------------------------------------------------------------*/  sock->events = 0;  /*-------------------------------------------------------------------*/  /* Promote soft error if timeout or connection abort occurred.       */  /*-------------------------------------------------------------------*/  if (sock->soft_error)  {    if (sock->error == ETIMEDOUT)    {      if (sock->type == SOCK_STREAM)        TcpDrop(sock, sock->soft_error);      else        sock->error = sock->soft_error;    }    else if (sock->error == ECONNABORTED)      sock->error = sock->soft_error;  }}/***********************************************************************//*     tcpDiag: Output TargetTCP diagnostics                           *//*                                                                     *//*       Input: type = type of diagnostic to report                    *//*                                                                     *//***********************************************************************/void tcpDiag(int type){  /*-------------------------------------------------------------------*/  /* Verify protocol has been initialized.                             */  /*-------------------------------------------------------------------*/  if (!Net.Initialized)  {    NetError(NULL, ENETDOWN);    return;  }  /*-------------------------------------------------------------------*/  /* Acquire exclusive access to protocol internals.                   */  /*-------------------------------------------------------------------*/  semPend(Net.IntSem, WAIT_FOREVER);  /*-------------------------------------------------------------------*/  /* If requested, report on socket use.                               */  /*-------------------------------------------------------------------*/  if (type & TCP_DIAG_SOCK)  {    TcpQuerySock();    UdpQuerySock();  }  /*-------------------------------------------------------------------*/  /* If requested, display ARP table.                                  */  /*-------------------------------------------------------------------*/  if (type & TCP_DIAG_ARP)    NetQueryArp();  /*-------------------------------------------------------------------*/  /* If requested, report on buffer use.                               */  /*-------------------------------------------------------------------*/  if (type & TCP_DIAG_BUFS)    NetQueryBuf();

⌨️ 快捷键说明

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