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

📄 tcp_data.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************//*                                                                     *//*   Module:  tcp_ip/tcp/tcp_data.c                                    *//*   Release: 2001.3                                                   *//*   Version: 2001.0                                                   *//*   Purpose: TCP Input Data Processing                                *//*                                                                     *//*---------------------------------------------------------------------*//*                                                                     *//*               Copyright 2001, 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.h"#include <string.h>#include <stdlib.h>/***********************************************************************//* Configuration                                                       *//***********************************************************************/#define OOS_RECORDS     20/***********************************************************************//* Type Definitions                                                    *//***********************************************************************/typedef struct srec{  struct srec *next;  NetBuf *buf;  tcpseq seq;  int len;} SegRecord;/***********************************************************************//* Global Variable Definitions                                         *//***********************************************************************/static SegRecord SegRecords[OOS_RECORDS];static SegRecord *FreeRecQ;/***********************************************************************//* Local Function Definitions                                          *//***********************************************************************//***********************************************************************//*     add_seg: Add segment to "received out of order" segment queue   *//*                                                                     *//*       Input: sock = pointer to socket control block                 *//*                                                                     *//***********************************************************************/static void add_seg(SOCKET sock){  SegRecord *seg_record;  tcpseq seq = Net.Tcp->seq_num;  /*-------------------------------------------------------------------*/  /* Try to allocate a segment record, returning if unable.            */  /*-------------------------------------------------------------------*/  if (FreeRecQ == NULL)    return;  seg_record = FreeRecQ;  FreeRecQ = FreeRecQ->next;  /*-------------------------------------------------------------------*/  /* Initialize segment record.                                        */  /*-------------------------------------------------------------------*/  seg_record->seq = seq;  seg_record->len = RxBuf->app_len;  /*-------------------------------------------------------------------*/  /* If queue is empty, make this the first entry.                     */  /*-------------------------------------------------------------------*/  if (sock->oosq == NULL)  {    sock->oosq = seg_record;    seg_record->next = NULL;  }  /*-------------------------------------------------------------------*/  /* Else insert record according to sequence number order.            */  /*-------------------------------------------------------------------*/  else  {    SegRecord *next = sock->oosq;    /*-----------------------------------------------------------------*/    /* If sequence number less than first entry, new queue head.       */    /*-----------------------------------------------------------------*/    if (SEQ_LT(seq, next->seq))    {      seg_record->next = next;      sock->oosq = seg_record;    }    /*-----------------------------------------------------------------*/    /* Search queue for sequence number greater than this segment's.   */    /*-----------------------------------------------------------------*/    else    {      SegRecord *prev;      for (;;)      {        /*-------------------------------------------------------------*/        /* If sequence numbers match, free record and return.          */        /*-------------------------------------------------------------*/        if (seq == next->seq)        {          seg_record->next = FreeRecQ;          FreeRecQ = seg_record;          return;        }        /*-------------------------------------------------------------*/        /* Save pointer to current record and advance to next.         */        /*-------------------------------------------------------------*/        prev = next;        next = next->next;        /*-------------------------------------------------------------*/        /* If queue end is reached, append record to end.              */        /*-------------------------------------------------------------*/        if (next == NULL)        {          prev->next = seg_record;          seg_record->next = NULL;          break;        }        /*-------------------------------------------------------------*/        /* If entry found with greater sequence number, insert record. */        /*-------------------------------------------------------------*/        if (SEQ_LT(seq, next->seq))        {          seg_record->next = next;          prev->next = seg_record;          break;        }      }    }  }  /*-------------------------------------------------------------------*/  /* Mark buffer as holding data and on segment queue.                 */  /*-------------------------------------------------------------------*/  RxBuf->flush = sock;  RxBuf->seg_record = seg_record;  /*-------------------------------------------------------------------*/  /* Save buffer pointer in segment record.                            */  /*-------------------------------------------------------------------*/  seg_record->buf = RxBuf;  /*-------------------------------------------------------------------*/  /* Append buffer to free list and prevent later prepend free.        */  /*-------------------------------------------------------------------*/  tcpRetRcvBuf(RxBuf);  RxBuf = NULL;}/***********************************************************************//* Global Function Definitions                                         *//***********************************************************************//***********************************************************************//*     TcpInit: Initialize TCP protocol software                       *//*                                                                     *//***********************************************************************/void TcpInit(void){  int i;  /*-------------------------------------------------------------------*/  /* Set initial segment sequence number.                              */  /*-------------------------------------------------------------------*/  Net.ISN = (rand() << 16) | rand();  /*-------------------------------------------------------------------*/  /* Initialize TCP socket list.                                       */  /*-------------------------------------------------------------------*/  TcpLruList.next_fwd = TcpLruList.next_bck = &TcpLruList;  /*-------------------------------------------------------------------*/  /* Initially link all segment records onto free list.                */  /*-------------------------------------------------------------------*/  FreeRecQ = &SegRecords[0];  for (i = 0; i < OOS_RECORDS; ++i)    SegRecords[i].next = &SegRecords[i + 1];  SegRecords[OOS_RECORDS - 1].next = NULL;}/***********************************************************************//*  TcpFreeOoQ: Free socket's out-of-order segment record queue        *//*                                                                     *//*       Input: sock = pointer to socket control block                 *//*                                                                     *//***********************************************************************/void TcpFreeOoQ(SOCKET sock){  SegRecord *srp;  while (sock->oosq)  {    /*-----------------------------------------------------------------*/    /* Remove record from socket's segment record list.                */    /*-----------------------------------------------------------------*/    srp = sock->oosq;    sock->oosq = sock->oosq->next;    /*-----------------------------------------------------------------*/    /* If buffer attached, clear flush flag.                           */    /*-----------------------------------------------------------------*/    if (srp->buf)    {      srp->buf->flush = NULL;      srp->buf->seg_record = NULL;      srp->buf = NULL;    }    /*-----------------------------------------------------------------*/    /* Add record to free segment record list.                         */    /*-----------------------------------------------------------------*/    srp->next = FreeRecQ;    FreeRecQ = srp;  }}/***********************************************************************//*     TcpData: Process current segment's data                         *//*                                                                     *//*       Input: sock = pointer to control block matched with segment   *//*                                                                     *//*     Returns: 0 if no errors, else -1                                *//*                                                                     *//***********************************************************************/int TcpData(SOCKET sock){  /*-------------------------------------------------------------------*/  /* If data sent and application not receiving, send reset and drop.  */  /*-------------------------------------------------------------------*/  if ((sock->rbuf == NULL) && RxBuf->app_len)  {    TcpReset();    TcpDrop(sock, ECONNABORTED);    return -1;  }  /*-------------------------------------------------------------------*/  /* Check for urgent data flag.                                       */  /*-------------------------------------------------------------------*/  if (Net.Tcp->flags & TCPF_URG)  {    /*-----------------------------------------------------------------*/    /* Calculate pointer to urgent data.                               */    /*-----------------------------------------------------------------*/    tcpseq up = Net.Tcp->seq_num + Net.Tcp->urg_ptr - 1;    /*-----------------------------------------------------------------*/    /* If first occurrence or newly extended, set flag and post event. */    /*-----------------------------------------------------------------*/    if (!(sock->flags & SF_RUPOK) || SEQ_GT(up, sock->rurg_seq))    {      sock->rurg_seq = up;      sock->flags |= SF_RUPOK;      NetPostEvent(sock, SE_URGENT);    }  }  /*-------------------------------------------------------------------*/  /* Check if run of contiguous sequence numbers has been extended.    */  /*-------------------------------------------------------------------*/  if (sock->rcv_nxt == Net.Tcp->seq_num)  {    /*-----------------------------------------------------------------*/

⌨️ 快捷键说明

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