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

📄 tcp.c

📁 ATmega103、ATmega128做的开发板web server源码
💻 C
📖 第 1 页 / 共 4 页
字号:
      return socketNr;
    }
  }
  return 0xff;
}

/*TCPaopen actively opens a connection to the given host and returns a
  pointer to the socket created for this connection*/
SOCKET *TCPaopen (unsigned int port, unsigned int ip0, unsigned int ip1, unsigned int MYport)
{
  static unsigned int myPort=1200;
  unsigned char socketNr;
  unsigned int *frameptr=&frame[TCP_DATA];
  SOCKET *tmpSocketptr;
  unsigned char j, temp = SREG;
  SOCKET *socketptr;
  TCB *tcbptr;
  
  _CLI();                   //Clear interrupt to ensure the frame is not overwritten while we make it.
  socketNr=TCPfindTCB();    //Find a free TCB.
  if (socketNr < TCP_MAX_SOCKETS)
  {
    tcbptr = &tcb[socketNr];
    socketptr = &sockets[socketNr];
    tcbptr->readOut=0;
    tcbptr->writeOut=0;
    tcbptr->readIn=0;
    tcbptr->writeIn=0;
    tcbptr->open = TRUE;
    socketptr->hisIP1 = ip1;
    socketptr->hisIP0 = ip0;
    socketptr->hisPort = port;
    socketptr->myPort = (MYport)?MYport:myPort++;      //If a portnumber is not given, choose the default one.
    tcbptr->sndWND = TCP_WIN_SIZE;
    tcbptr->ISS = tcbptr->sndNXT;                   // Use old value of sequencenr.
    tcbptr->sndUNA = tcbptr->ISS;
    tcbptr->sndWL1 = tcbptr->IRS;
    tcbptr->sndWL2 = tcbptr->sndUNA;
    tcbptr->CTL = TCP_SYN;
    *frameptr++ = 0x0204;
    *frameptr++ = (TCP_WIN_SIZE > 1460)?1460:TCP_WIN_SIZE;
    *frameptr++ = 0x0101;               //NOP to fill the two last words.
    *frameptr   = 0x0101;
    tcbptr->segLEN = 0x1c;
    tcbptr->segHdrLEN = 0x1c;             // This segment contains only the header
    socketptr->socketNr = socketNr;
    socketptr->state = HALF_OPEN;
    socketptr->next = NULL;
    socketptr->previous = NULL;
    tmpSocketptr = sockets;
    for (j=0;j<TCP_MAX_SOCKETS;j++) // Find the end of the linked list and connect to tail.
    {
//      tmpSocketptr = &sockets[j];
      if ( (tmpSocketptr->myPort == myPort) && (tmpSocketptr->next == NULL) && (socketptr != tmpSocketptr) ) 
      {
    	tmpSocketptr->next = socketptr;
	    socketptr->previous = tmpSocketptr;
    	break;
      }
      tmpSocketptr++;
    }
    prepareFrame(socketNr);
    transmitIP(tcbptr->segLEN, socketptr->hisIP0, socketptr->hisIP1, 6); //Send segment
    tcbptr->sndNXT++;
    tcbptr->state=TCP_STATE_SYN_SENT;
    SREG = temp;
    return socketptr;   //Return pointer to socket
  }
  SREG = temp;  //Unable to start a new connection.
  return NULL;
}

/*TCPlistenPort checks if someone listens to the given port.*/
char TCPlistenPort(unsigned int port, unsigned long ip)
{
  unsigned char i;
  LISTEN *listenptr = listenList;

  for (i=0;i<TCP_MAX_CONNECTIONS;i++)
  {
//    listenptr = &listenList[i];
    if ( (listenptr->portNr == port) && (listenptr->ip == ip) )
    {  
      return 1;
    }
    listenptr++;
  }
  return 0;
}
/* TCPget copies up to maxSize bytes from inBuffer to
   the application's buffer. The space in inBuffer is
   freed after the data has been copied. */
int TCPget(SOCKET *socket, int maxSize, char *buffer)
{
  unsigned int read = TCPread(socket, maxSize, buffer, 1); //Copy data to buffer

  tcb[socket->socketNr].readIn += read;                    //Update pointer to inBuffer.
  return read;                                             //Return number of bytes copied.
}

/* TCPread copies up to maxSize bytes from inBuffer to
   the application's buffer. The space in inBuffer is
   NOT freed after the data has been copied. If reset
   is set, TCPread starts to read from the start of data.
   If reset is not set, TCPread continues to read from
   where it ended last time.*/
int TCPread(SOCKET *socket, int maxSize, char *buffer, char reset)
{
  unsigned int unread,i;
  unsigned char socketNr = socket->socketNr;
  unsigned char *inbuffer, *startbuffer, *endbuffer;
  TCB *tcbptr;
  
  if (socketNr == 0xff)  //If the socket does not exists.
  {
    return 0;
  }
  tcbptr = &tcb[socketNr];
  tcbptr->readIn = (tcbptr->readIn)%TCP_WIN_SIZE;
  tcbptr->writeIn = (tcbptr->writeIn)%TCP_WIN_SIZE;
  if (reset)
  {
    tcbptr->TMPreadIn = tcbptr->readIn;
  }
  else
  {
    tcbptr->TMPreadIn = (tcbptr->TMPreadIn)%TCP_WIN_SIZE;  //Make sure the pointer is within buffer
  }
  unread = writtenIn(socketNr); //Check how much data to be read.
  if ( !unread )
  {
    return 0;
  }
  else if ( unread > maxSize )  //Make sure not more than max is copied.
  {
    unread = maxSize;
  }
  inbuffer = &tcbptr->inBuffer[tcbptr->TMPreadIn];
  startbuffer = &tcbptr->inBuffer[0];
  endbuffer = &tcbptr->inBuffer[TCP_WIN_SIZE-1];
  for (i=0;i<unread;i++)
  {
    *buffer++ = *inbuffer++;
    if (inbuffer > endbuffer)     //If pointer exceeds buffer
    {
      inbuffer = startbuffer;     //Set pointer to start of buffer
    }
  }
  tcbptr->TMPreadIn += unread;
  return unread;
}

/* TCPreadln copies one line, up to maxSize bytes, from inBuffer to
   the application's buffer. The space in inBuffer is
   NOT freed after the data has been copied. If reset
   is set, TCPreadln starts to read from the start of data.
   If reset is not set, TCPreadln continues to read from
   where it ended last time.*/
int TCPreadln(SOCKET *socket, int maxSize, char *buffer, char reset)
{
  unsigned int i;
  unsigned int read = TCPread(socket, maxSize, buffer, reset);

  for (i=0;i<read-1;i++)
  {
    if ( (buffer[i] == '\r') || (buffer[i] == '\n') )  //Find a CRLF or LFCR and return the length of the line
    {
      if ( (buffer[i+1] == '\r') || (buffer[i+1] == '\n') )
      {
        tcb[socket->socketNr].TMPreadIn -= (read - (i+2));
        return (i+2);
      }
    }
  }
  return read;
}


/*TCPsize returns the amount of data in inBuffer.*/
int TCPsize(SOCKET *socket)
{
  return (writtenIn(socket->socketNr));
}

/*TCPbufferSpace returns the amount of free space in outBuffer.*/
int TCPbufferSpace(SOCKET *socket)
{
  return ((TCP_WIN_SIZE-writtenOut(socket->socketNr))-2);
}

/*TCPbufferFlush flushes the data in the inBuffer.*/
void TCPbufferFlush(SOCKET *socket)
{
  TCB *tcbptr = &tcb[socket->socketNr];
  tcbptr->readIn = tcbptr->writeIn;
}

/*TCPsend copies data from buffer to outBuffer for sending.
  If size is greater than the amount of free space, only the data
  that fits into the buffer is copied.*/
int TCPsend(SOCKET *socket, int size, char *buffer)
{
  unsigned int unwritten,i;
  TCB *tcbptr = &tcb[socket->socketNr];
  unsigned char *outbuffer, *startbuffer, *endbuffer;
  
  unwritten = TCP_WIN_SIZE - (writtenOut(socket->socketNr)+1); //Find amount of free space. Let there be one byte free to avoid
  if (socket->socketNr == 0xff)                                //that writeOut-pointer passes readOut-pointer.
  {
    return 0;       //Return 0 if socket does not exists.
  }
  if ( unwritten > size )
  {
    unwritten = size;     
  }
  outbuffer = &tcbptr->outBuffer[tcbptr->writeOut];
  startbuffer = tcbptr->outBuffer;
  endbuffer = &tcbptr->outBuffer[TCP_WIN_SIZE-1];
  for (i=0;i<unwritten;i++)
  {
    *outbuffer++ = *buffer++;  //Copy byte to outBuffer.
    if (outbuffer > endbuffer)
    {
      outbuffer = startbuffer;  //if outbuffer-ptr exceeds the end of buffer, set to start of buffer.
    }
  }
  tcbptr->writeOut += unwritten;
  return unwritten;
}

/*TCPsend_P do the same thing as TCPsend, but it accepts data
  from program space (FLASH).*/
int TCPsend_P(SOCKET *socket, int size, char flash *buffer)
{
  unsigned int unwritten,i;
  TCB *tcbptr = &tcb[socket->socketNr];
  unsigned char *outbuffer, *startbuffer, *endbuffer;

  if (socket->socketNr == 0xff)
  {
    return 0;
  }
  unwritten = TCP_WIN_SIZE - (writtenOut(socket->socketNr)+1);
/*  if ( unwritten > size )
  {
    unwritten = size;
  }
*/
// NOTE : Rewritten for ew2.25b, due to possible compiler bug, strlen_P returns 1 extra byte
  if ( unwritten > (size-1))
  {
    unwritten = size-1;
  }

  outbuffer = &tcbptr->outBuffer[tcbptr->writeOut];
  startbuffer = tcbptr->outBuffer;
  endbuffer = &tcbptr->outBuffer[TCP_WIN_SIZE-1];
  for (i=0;i<unwritten;i++)
  {
    *outbuffer++ = *buffer++;
    if (outbuffer > endbuffer)
    {
      outbuffer = startbuffer;
    }
  }
  tcbptr->writeOut += unwritten;
  return unwritten;
}

/*TCPstop deletes the entry in listenList to stop
  listening on a port*/
void TCPstop(unsigned int port, unsigned long ip)
{
  unsigned char i;
  LISTEN *listenptr = listenList;
  
  for (i=0;i<TCP_MAX_CONNECTIONS;i++)  //For every entry
  {
//    listenptr = &listenList[i];
    if ( (listenptr->portNr == port) && (listenptr->ip == ip) )  //If the entry match given data
    {
      listenptr->portNr = 0;    //Delete the entry.
      listenptr->ip = 0;
    }
    listenptr++;
  }
}

/*TCPclose closes a connection gently after all data is sent.*/
void TCPclose(SOCKET *socket)
{
  TCB *tcbptr = &tcb[socket->socketNr];
  tcbptr->readIn = tcbptr->writeIn;
  tcbptr->open = FALSE;
  socket->state = HALF_CLOSED;
}

/*TCPabort aborts the connection imidiately and
  sends a reset to the other host.*/
void TCPabort(SOCKET *socket)
{
  unsigned char socketNr = socket->socketNr;
  TCB *tcbptr = &tcb[socketNr];

  tcbptr->CTL = TCP_ACK|TCP_RST;
  tcbptr->segLEN = 20;
  tcbptr->segHdrLEN = 20;
  prepareFrame(socketNr);
  transmitIP (tcbptr->segLEN, socket->hisIP0, socket->hisIP1, 6);
  deleteSocket(socketNr);
}

/*TCPinit initialize TCP before use. Must be called before
  any connections may be accepted. */
void TCPinit( void )
{
  unsigned char i;
  TCB *tcbptr = tcb;
  SOCKET *socketptr;
  LISTEN *listenptr;
  RT *RTptr;
  
  for (i=0; i<TCP_MAX_SOCKETS;i++)  //Delete all TCBs
  {
//    tcbptr = &tcb[i];
    tcbptr->open = FALSE;
    tcbptr->state = TCP_STATE_CLOSED;
    tcbptr->readIn = 0;
    tcbptr->readOut = 0;
    tcbptr->writeIn = 0;
    tcbptr->writeOut = 0;
    tcbptr++;
  }
  socketptr = sockets;
  for (i=0;i<TCP_MAX_SOCKETS;i++)  //Delete all sockets
  {
//    socketptr = &sockets[i];
    socketptr->socketNr = 0xff;
    socketptr->hisIP0 = 0;
    socketptr->hisIP1 = 0;
    socketptr->hisPort = 0;
    socketptr->myPort = 0;
    socketptr->state = UNLOCKED;
    socketptr->next = NULL;
    socketptr->previous = NULL;
    socketptr++;
  }
  listenptr = listenList;  
  for (i=0;i<TCP_MAX_CONNECTIONS;i++) //Delete all ports in listenList.
  {
//    listenptr = &listenList[i];
    listenptr->portNr = 0;
    listenptr->ip = 0xffffffff;
    listenptr++;
  }
  RTptr = RTframes;
  for (i=0;i<TCP_NUMBER_RT_BUF;i++)  //Delete all segments in retransmission buffer
  {
//    RTframes[i].socketNr = 0xff;
    RTptr++->socketNr = 0xff;
  }
}




⌨️ 快捷键说明

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