单片机tcp/ip问题

bdywsled   2007-4-13 20:55 楼主
我现在做个程序,从计算机上的1000端口发送数据过来,但在单片机上接收到上位机来的命令字,不知道怎么发送单片机上的数据到上位机,哪位大虾指点一下

回复评论 (12)

void tcp_rcve(UCHAR xdata * inbuf, UINT len)
{
   UCHAR idata i, j, nr;
   UINT idata result, header_len, data_len;
   TCP_HEADER xdata * tcp;
   IP_HEADER xdata * ip;
   ULONG idata sum;
   
   // IP header is always 20 bytes so message starts at index 34      
   tcp = (TCP_HEADER xdata *)(inbuf + 34);
   ip = (IP_HEADER xdata *)(inbuf + 14);
                                  
        // Compute TCP checksum including 12 byte pseudoheader
        // Sum source_ipaddr, dest_ipaddr, and entire TCP message
        sum = (ULONG)cksum(inbuf + 26, 8 + len);
               
        // Add in the rest of pseudoheader which is
        // protocol id and TCP segment length
        sum += (ULONG)0x0006;     
        sum += (ULONG)len;

        // In case there was a carry, add it back around
        result = (UINT)(sum + (sum >> 16));
               
        if (result != 0xFFFF)
        {
                return;
   }

   
        // See if message is for http server
        if (tcp->dest_port != HTTP_PORT)       
   {
      
      tcp_send(FLG_RST, 20, NO_CONNECTION);
      return;
   }
   
   // Capture sender's IP address and port number
   sender_ipaddr = ip->source_ipaddr;
   sender_tcpport = tcp->source_port;
   
   // See if the TCP segment is from someone we are already
   // connected to.
   for (i=0; i < 5; i++)
   {
      if ((ip->source_ipaddr == conxn.ipaddr) &&
         (tcp->source_port == conxn.port))
      {   
         nr = i;
         break;
      }      
   }
   
   // If i = 5, we are not connected. If it is a SYN then assign
   // a temporary conection  to it for processing
   if (i == 5)
   {
      if (tcp->flags & FLG_SYN)
      {
         // Find first unused connection (one with IP = 0)
         for (j=0; j < 5; j++)
         {
            if (conxn[j].ipaddr == 0)
            {
               nr = j;
               // Initialize new connection
               conxn[nr].state = STATE_LISTEN;
               break;
            }
         }
      
         // If all connections are used then drop msg
         if (j == 5) return;
         
        
      }
   }


   // By now we should have a connection number in range of 0-4
   // Do a check to avoid any chance of exceeding size of struct
   if (nr > 4)
   {
      return;
   }

   // Eventually put in protection against wrapping sequence
   // numbers, for now make the client start over if his
   // sequence number is close to wrapping
   if (tcp->sequence > 0xFFFFFF00L)
   {
                conxn[nr].ipaddr = 0;                       
                tcp_send(FLG_RST, 20, NO_CONNECTION);
                return;               
   }
           
   // Handle messages whose action is mostly independent of state
   // such as RST, SYN, and segment with no ACK.  That way the
        // state machine below does not need to worry about it.
   if (tcp->flags & FLG_RST)
   {
      // An RST does not depend on state at all.  And it does
      // not count as data so do not send an ACK here.  Close
      // connection
      conxn[nr].ipaddr = 0;
      return;
   }
       
        else if (tcp->flags & FLG_SYN)
        {
           // A SYN segment only makes sense if connection is in LISTEN
           if ((conxn[nr].state != STATE_LISTEN) &&
          (conxn[nr].state != STATE_CLOSED))
                {
                        conxn[nr].ipaddr = 0;                       
                          tcp_send(FLG_RST, 20, NO_CONNECTION);
                          return;               
                }
        }
       
        else if ((tcp->flags & FLG_ACK) == 0)
        {
                // Incoming segments except SYN or RST must have ACK bit set
                 // See TCP/IP Illustrated, Vol 2, Page 965
      // Drop segment but do not send a reset
                return;
        }
          
   // Compute length of header including options, and from that
   // compute length of actual data
   header_len =  (tcp->flags & 0xF000) >> 10;
   data_len = len - header_len;


         
   // Handle TCP state machine for this connection
   switch (conxn[nr].state)
   {
      case STATE_CLOSED:
      case STATE_LISTEN:
            
点赞  2007-4-13 20:57
// If incoming segment contains SYN and no ACK, then handle
      if ((tcp->flags & FLG_SYN) && ((tcp->flags & FLG_ACK) == 0))
      {
         // Capture his starting sequence number and generate
         // my starting sequence number
         // Fill in connection information
         conxn[nr].ipaddr = ip->source_ipaddr;
         conxn[nr].port = tcp->source_port;
         conxn[nr].state = STATE_LISTEN;
         conxn[nr].his_sequence = 1 + tcp->sequence;
         conxn[nr].his_ack = tcp->ack_number;
         
         // Use system clock for initial sequence number
         conxn[nr].my_sequence = initial_sequence_nr;
         initial_sequence_nr += 64000L;
         EA = 1;                  
                  
         // Send header options with the next message
         // Since timestamps are optional and we do not use
         // them, do not have to send them
         // After sending the SYN ACK the client browser will
         // blast me with 2 messages, an ACK, and a HTTP GET
         tcp_send(FLG_SYN | FLG_ACK, 28, nr);
         
         // My SYN flag increments my sequence number
         // My sequence number is always updated to point to
         // the next byte to be sent.  So the incoming ack
         // number should equal my sequence number  
         conxn[nr].my_sequence++;
      
         conxn[nr].state = STATE_SYN_RCVD;
      }
                else
      {
         // Sender is out of sync so send reset
         conxn[nr].ipaddr = 0;
         tcp_send(FLG_RST, 20, NO_CONNECTION);   
      }
                break;


      case STATE_SYN_RCVD:
      // He may already be sending me data - should process it
                conxn[nr].his_sequence += data_len;
      conxn[nr].his_ack = tcp->ack_number;
            
      if (tcp->flags & FLG_FIN)
                {
                   // His FIN counts as a byte of data
         conxn[nr].his_sequence++;
         tcp_send(FLG_ACK, 20, nr);
         conxn[nr].state = STATE_CLOSE_WAIT;
               
                // At this point we would normally wait for the        application
         // to close.  For now, send FIN right away.
         tcp_send(FLG_FIN | FLG_ACK, 20, nr);
         conxn[nr].my_sequence++;   // For my FIN
         conxn[nr].state = STATE_LAST_ACK;
      }

                // Make sure he is ACKing my SYN
                else if (tcp->ack_number == conxn[nr].my_sequence)
      {
         conxn[nr].state = STATE_ESTABLISHED;
         // If sender sent data ignore it and he will resend
         // Do not send response because we received no
         // data... wait for client to send something to me
      }
      break;


      case STATE_ESTABLISHED:
      conxn[nr].his_ack = tcp->ack_number;
           
      if (tcp->flags & FLG_FIN)
                {
                   // His FIN counts as a byte of data
         conxn[nr].his_sequence++;
         tcp_send(FLG_ACK, 20, nr);
         conxn[nr].state = STATE_CLOSE_WAIT;
               
                // At this point we would normally wait for the        application
         // to close.  For now, send FIN immediately.
         tcp_send(FLG_FIN | FLG_ACK, 20, nr);
         conxn[nr].my_sequence++;   // For my FIN
         conxn[nr].state = STATE_LAST_ACK;
      }
                else if (data_len != 0)
      {
                        // Received normal TCP segment from sender with data
              // Send an ACK immediately and pass the data on to
                        // the application
                        conxn[nr].his_sequence += data_len;
         tcp_send(FLG_ACK, 20, nr);                 // Send ACK
                
                                                                                                                  
                        // Send pointer to start of TCP payload
                        // http_server increments my sequence number when
         // sending so don't worry about it here
         result = http_server(inbuf, header_len, nr, 0);  //Êý¾Ý´«Ê亯Êý
                                                               
                        // Start timer to close conxn if no activity
                        conxn[nr].inactivity = INACTIVITY_TIME;
                }
           break;


      case STATE_CLOSE_WAIT:
      // With this code, should not get here
      ;
      break;

      
      case STATE_LAST_ACK:
      conxn[nr].his_ack = tcp->ack_number;
            
      // If he ACK's my FIN then close
      if (tcp->ack_number == conxn[nr].my_sequence)
      {
         conxn[nr].state = STATE_CLOSED;
         conxn[nr].ipaddr = 0;  // Free up struct area
         just_closed = TRUE;
      }
      break;

      
      case STATE_FIN_WAIT_1:
      // He may still be sending me data - should process it
                conxn[nr].his_sequence += data_len;
      conxn[nr].his_ack = tcp->ack_number;
                  
      if (tcp->flags & FLG_FIN)
      {
         // His FIN counts as a byte of data
         conxn[nr].his_sequence++;
         tcp_send(FLG_ACK, 20, nr);
         
         // If he has ACK'd my FIN then we can close connection
         if (tcp->ack_number == conxn[nr].my_sequence)
                        {
                 conxn[nr].state = STATE_TIME_WAIT;
               
                 conxn[nr].state = STATE_CLOSED;
                 conxn[nr].ipaddr = 0;  // Free up connection
                 just_closed = TRUE;
              }
                        else
                        {
                                // He has not ACK'd my FIN.  This happens when there is a simultaneous
                                // close - I got his FIN but he has not yet ACK'd my FIN
                                conxn[nr].state = STATE_CLOSING;
                        }
                }
      else if (tcp->ack_number == conxn[nr].my_sequence)
      {
         // He has ACK'd my FIN but has not sent a FIN yet himself
         conxn[nr].state = STATE_FIN_WAIT_2;
      }
      break;

      
      case STATE_FIN_WAIT_2:
      // He may still be sending me data - should process it
                conxn[nr].his_sequence += data_len;
      conxn[nr].his_ack = tcp->ack_number;
      
      if (tcp->flags & FLG_FIN)
      {
         conxn[nr].his_sequence++; // For his FIN flag
         tcp_send(FLG_ACK, 20, nr);
         conxn[nr].state = STATE_TIME_WAIT;
         conxn[nr].state = STATE_CLOSED;
         conxn[nr].ipaddr = 0;  // Free up struct area
         just_closed = TRUE;
      }
      break;
            
            
      case STATE_TIME_WAIT:
      // With this code, should not get here
       ;
      break;

      
      case STATE_CLOSING:
      // Simultaneous close has happened. I have received his FIN
      // but he has not yet ACK'd my FIN.  Waiting for ACK.
                // Will not receive data in this state
                conxn[nr].his_ack = tcp->ack_number;
                     
                if (tcp->ack_number == conxn[nr].my_sequence)
      {
                   conxn[nr].state = STATE_TIME_WAIT;
         
         // Do not send any response to his ACK
         conxn[nr].state = STATE_CLOSED;
         conxn[nr].ipaddr = 0;  // Free up struct area
         just_closed = TRUE;
      }
      break;

      
      default:
      ;
      break;
   }
   
   // This is for debug, to see when conxn closes
   if (just_closed)
   {
      just_closed = FALSE;
     
   }
}

接收原程序,但到了应用层就不知道怎么弄了,求各位大虾了
点赞  2007-4-13 20:57
怎么没的人回答呢
点赞  2007-4-14 23:10
mark,帮up
点赞  2007-4-17 11:34
没试过,1000端口没用过,是什么总线?
点赞  2007-4-19 19:26
老实说,不知道你想问什么,
描述清楚一点,世界将会相当的美好...
点赞  2007-4-20 11:42
网络方式发送数据到pc需要有网卡硬件。
点赞  2007-4-20 15:35
你单片机端网络使用的是什么芯片啊,是8019么,还是别的,有没有用嵌入式内核,你的问题提得太泛泛了,不好回答啊
点赞  2007-4-20 20:10
你单片机里有没有实现tcp/ip协议。实现了就可以收发啦
点赞  2007-5-11 09:34
你单片机是什么方式和PC通讯 网卡?还是通过点对点方式
然后你才能决定如何通过什么协议进行发送
点赞  2007-5-11 09:52
通过串口吗?学习中。
点赞  2007-5-11 10:09
你在单片机里面需要运行TCP/IP协议栈的,ZLIP可以实现这个功能:http://www.zlmcu.com/ZLIP/zlip_introduction.htm
点赞  2008-9-25 22:15
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复