找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3174|回復: 0
打印 上一主題 下一主題
收起左側(cè)

嵌入式的TCP+IP協(xié)議的完整C源程序

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:232914 發(fā)表于 2017-9-14 10:44 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
做一個項目涉及到的tcp/ip 源代碼




所有資料51hei提供下載:
TCP IP協(xié)議的完整C源程序.rar (26.62 KB, 下載次數(shù): 26)


源程序如下:

  1. // 版權(quán) 2003, 王衛(wèi)無,四川綿陽岷山集團有限公司--研究開發(fā)中心
  2. // wolver@minshan-inc.com
  3. // 保留一切權(quán)利
  4. //
  5. // 如果符合以下條件,則無論是以原代碼或非原代碼代碼形式,且不論是否修改,
  6. // 再分發(fā)和使用本軟件都是被允許的。
  7. // 1. 原代碼的再分發(fā)必須保留上述的版權(quán)聲明、本條件說明和以下免責聲明。
  8. // 2. 非原代碼形式的再分發(fā),必須在證明文件和(或)其它一同提供的材料中重新
  9. //    作上述的版權(quán)聲明、本條件說明和以下免責聲明。
  10. // 3. 一切提及本軟件和使用的廣告材料必須顯示以下致謝:
  11. //    本產(chǎn)品包含王衛(wèi)無(四川綿陽岷山集團有限公司--研究開發(fā)中心)開發(fā)的軟件。
  12. // 4. 如果沒有預先得到特定的書面許可,不能用作者的名字來宣傳推廣基于本軟件得到
  13. //    的產(chǎn)品。
  14. //
  15. // 免責聲明:
  16. // 本軟件是由某某作者提供,如果出現(xiàn)以下情況,作者都不承擔任何責任。
  17. // 1. 因作者的說明以及任何明確的或暗示的保證(包括但不限于表達某種商業(yè)性和適合某一
  18. //    特定目的暗示性保證)而產(chǎn)生的損失。
  19. // 2. 無論在何種情況下,對使用本軟件造成的任何直接的、間接的、偶然的、特定的、可預
  20. //    見性的和連帶產(chǎn)生的損失(包括但不限于獲取產(chǎn)品和服務(wù)、作用喪失、數(shù)據(jù)遺失、利益損
  21. //    失或商業(yè)干預),無論這些損失是怎樣造成的,并且是以何種方式闡釋責任。
  22. // 3. 任何因使用本軟件而相關(guān)的合同、嚴格賠償責任和侵權(quán)行為(包含:疏忽或其它)的損失,
  23. //    甚至即便是可能的此類已經(jīng)明示或暗示的損失。
  24. ///


  25. #include "system.h"
  26. #include "tcpip.h"
  27. #include "drivers.h"

  28. // 定義應用:1 表示開啟功能,0 表示關(guān)閉功能
  29. #define cTCP_RS232   1    // TCP <-> RS232 的應用,只用于服務(wù)模式
  30. #define cTCP_ADAC    1    // TCP <-> Audio, 主要用于服務(wù),也可以用于客戶。要求高帶寬: > 912Kbit



  31. // 分配本地用戶自定義服務(wù)模式應用TCP端口號,不能與知名端口相同!如:23, 80
  32. // 注意:對不同的TCP事件使用不同的本地端口號,有助于快速查找TCP事件而不需要判斷IP是否相同!
  33. //       這樣做能使本地快速響應。
  34. #define cTCP_ListenPort_TEST   0x1000   // 4096

  35. #if cTCP_RS232 == 1
  36. #define cTCP_ListenPort_RS232  0x2000   // 8192
  37. #endif

  38. #if cTCP_ADAC == 0
  39. #define cTCP_ListenPort_ADAC   0x3000   // 12288
  40. #endif

  41. // 客戶應用模式的本地TCP端口號。不能與知名端口相同!如:23, 80
  42. // 注意:對不同的TCP事件使用不同的本地端口號(包括:本地偵聽端口),有助于快速查找TCP事件而
  43. //       不需要判斷IP是否相同!這樣做能使本地快速響應。
  44. #if (cTCP_ADAC == 1) && (TCP_ACTIVE_OPEN == 1)
  45. #define cTCP_ActivePort_ADAC  0x3001   // 12289
  46. #endif




  47. // 分配系統(tǒng)應用臨時緩沖區(qū)(按 wrod 存儲)
  48. UINT16 guwAppBuf[cAppSizeMax];

  49. //--------------------------------------------------------------------------------------

  50. main(){
  51. #if  TCP_ACTIVE_OPEN == 1
  52.         UINT16 temp[2];
  53. #endif


  54. // 1. Hardware initialize: SPCE061A
  55.         SP_IO_INIT();

  56. // 2. Open and Enable Hardware interrupt 2Hz and Clear WatchDog!
  57.         SP_OpenTime2();

  58. // 3. Hardware initialize: RTL8019AS
  59.         RTL8019AS_RESET();
  60.         RTL8019AS_INIT();

  61. // 4. vIP4 TCP/IP initialize
  62.         msip_Init();

  63. // 5. We listen test port
  64.         msip_Listen(cTCP_ListenPort_TEST);                // 用于偵聽來自鏈路測試的TCP包


  65. #if cTCP_RS232 == 1
  66.         SP_UART_INIT(C_UART_Baud_115200);                // Hardware initialize: UART of SPCE061A

  67.         msip_Listen(cTCP_ListenPort_RS232);                // 用于偵聽來自RS232的TCP包
  68. #endif


  69. #if cTCP_ADAC == 1
  70. //        SP_ADAC_INIT(cSample_4096);                                // Open ADAC
  71. //        SP_ADAC_INIT(cSample_8192);                                // Open ADAC
  72. //        SP_ADAC_INIT(cSample_16384);                        // Open ADAC
  73. //        SP_ADAC_INIT(cSample_32768);                        // Open ADAC
  74. //        SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC

  75.         msip_Listen(cTCP_ListenPort_ADAC);                // 用于偵聽來自遠端的Audio的TCP包
  76. #endif


  77. #if (cTCP_ADAC == 1) && (TCP_ACTIVE_OPEN == 1)
  78. // for test audio, wo active link remote: 192.168.0.60
  79.         temp[0] = ((192<<8)|168);
  80.         temp[1] = ((0<<8)|30);
  81.         msip_Connect(cTCP_ActivePort_ADAC, temp, cTCP_ListenPort_ADAC);
  82. #endif



  83. // 6. We do TCP/IP Check Loop
  84. loop:
  85.         // 接收新的以太包,并處理
  86.         if ((guwEthLen = ether_Receive()) != 0){
  87.                 switch (cptEthHdrBuf->EthType){
  88.                 case cEthType_Arp:
  89.                         msip_Arp_In();
  90.                         break;
  91.                 case cEthType_Ip:
  92.                         msip_Input();
  93.                 }
  94.         }

  95.         // ARP表老化處理
  96.         if (guwMsg_Route & cM_ARP_TIME){
  97.                 msip_Arp_Time();
  98.         }

  99.         // TCP事件輪詢
  100.         if (guwMsg_Route & cM_TCP_PERIODIC){
  101.                 msip_Periodic();
  102.         }

  103.     goto loop;

  104. }



  105. // SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB


  106. //--------------------------------------------------------------------------------------
  107. //
  108. //      |--------------|       |-----|----------|------|       |------|--------|
  109. //      |工業(yè)設(shè)備|RS232| <---> |RS232|核心嵌入板|TCP/IP| <---> |TCP/IP|普通PC機|
  110. //      |--------------|       |-----|----------|------|       |------|--------|
  111. //
  112. //-------------------------------------------------------------------------------------
  113. void userapp(){

  114.         switch (gptConn->LocalPort){
  115. #if cTCP_RS232 == 1
  116.         case cTCP_ListenPort_RS232:
  117.                 goto link_rs232;
  118. #endif

  119. #if cTCP_ADAC == 1        // ADAC 工作時:由于雙向通訊,所以Listen和Active處理是一樣的!
  120.         case cTCP_ListenPort_ADAC:
  121.                 goto link_adac_listen;
  122. #endif

  123. #if (cTCP_ADAC == 1) && (TCP_ACTIVE_OPEN == 1)        // ADAC 工作時:由于雙向通訊,所以Listen和Active處理是一樣的!
  124.         case cTCP_ActivePort_ADAC:
  125.                 goto link_adac_active;
  126. #endif

  127.         case cTCP_ListenPort_TEST:
  128.                 goto test_net;

  129.         default:
  130.                 return;
  131.         }


  132. #if cTCP_RS232 == 1
  133. link_rs232:         // 與RS232透明傳輸通訊:本系統(tǒng)的一個應用。


  134. // 以下事件的過慮判斷并不按照事件發(fā)生的順序,是因為有些事件通常只會發(fā)生一次,
  135. // 從而在大多數(shù)其它經(jīng)常發(fā)生的事件狀態(tài)下,減少對那些事件的過濾判斷,以提高速度!!!

  136.         if (msip_Poll() || msip_Acked()){        // 如果RS232有數(shù)據(jù)要發(fā)送,就轉(zhuǎn)發(fā)TCP數(shù)據(jù)段!
  137.                 if (guwUartRxLen > 0) {        // 根據(jù)guwUartRxLen判斷是否轉(zhuǎn)發(fā)RS232數(shù)據(jù)
  138.                         MEMCPY(guwUartRxLen, guwUartRxBuf, cpTcpData);
  139.                         guwEthLen = guwUartRxLen;
  140.                         guwUartRxLen = 0;
  141.                         gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  142.                 } else        if (gptConn->PollTime++ > 3*cTCP_MAX_POLL){        // 太長時間空閑(900秒),終止連接!
  143.                                 msip_Close();
  144.                 }

  145.                 return;
  146.         }

  147.         if (msip_NewData()){        // 收到TCP數(shù)據(jù)包,轉(zhuǎn)發(fā)給RS232
  148.                 if (guwEthLen > 0){
  149.                         SP_UART_TX(guwEthLen, cpTcpData);
  150.                         guwEthLen = 0;
  151.                 }
  152.                 if (guwUartRxLen > 0) {        // 根據(jù)guwUartRxLen判斷是否轉(zhuǎn)發(fā)RS232數(shù)據(jù)
  153.                         MEMCPY(guwUartRxLen, guwUartRxBuf, cpTcpData);
  154.                         guwEthLen = guwUartRxLen;
  155.                         guwUartRxLen = 0;
  156.                         gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  157.                 }

  158.                 gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  159.                 return;
  160.         }

  161.         if (msip_Connected()){
  162.                 gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  163.                 guwEthLen = 0;                        // 釋放TCP數(shù)據(jù)區(qū)

  164.                 return;
  165.         }


  166. //        if (msip_Aborted() || msip_Closed()){        // 如果異常關(guān)閉,那就關(guān)閉當前連接
  167.                 // Nothing to do!
  168. //                return;
  169. //        }

  170.         return;
  171. #endif



  172. #if cTCP_ADAC == 1        // ADAC 工作時:由于雙向通訊,所以Listen和Active處理是一樣的!
  173. link_adac_listen:
  174.         if (msip_Acked()){   // 如果有A/D數(shù)據(jù)要發(fā)送,就轉(zhuǎn)發(fā)TCP數(shù)據(jù)包
  175.                 /*
  176.                 if (guwMicRxLen > 0) {        // 根據(jù)guwMicRxLen判斷是否轉(zhuǎn)發(fā)Audio數(shù)據(jù)
  177.                         SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC
  178.                         MEMCPY(guwMicRxLen, guwMicRxBuf, cpTcpData);
  179.                         guwEthLen = guwMicRxLen;
  180.                         guwMicRxLen = 0;                // A/D 轉(zhuǎn)換計數(shù)復位
  181.                         SP_OPEN_FIQ();                        // 開啟FIQ中斷,同時也開啟了ADAC
  182.                         gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  183.                 } */
  184.                 guwEthLen = 0;
  185.                 return;
  186.         }


  187.         if (msip_NewData()){
  188.                 /*
  189.                 if (guwEthLen > 0){        // 收到Audio數(shù)據(jù)包
  190.                          // 如果上次沒有轉(zhuǎn)換完,就等....
  191.                         while(guwDAC1TxLen < guwDAC1TotalLen);
  192.                         // 如果轉(zhuǎn)換完,就復制buffer
  193.                         SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC
  194.                         if (guwEthLen > cDAC1_MAXLEN){  // 攔截超長bytes部分
  195.                                 guwEthLen = cDAC1_MAXLEN;
  196.                         }
  197.                         MEMCPY(guwEthLen, cpTcpData, guwDAC1TxBuf); // 將TCP數(shù)據(jù)Audio復制給DAC1的buffer
  198.                         guwDAC1TxLen = 0;                           // DAC1 轉(zhuǎn)換計數(shù)復位
  199.                         guwDAC1TotalLen = guwEthLen;        // DAC1 轉(zhuǎn)換buffer總長
  200.                         SP_OPEN_FIQ();                                        // 開啟FIQ中斷,同時也開啟了ADAC

  201.                         guwEthLen = 0;
  202.                 }
  203.                 if (guwMicRxLen > 0) {        // 根據(jù)guwMicRxLen判斷是否轉(zhuǎn)發(fā)Audio數(shù)據(jù)
  204.                         SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC
  205.                         MEMCPY(guwMicRxLen, guwMicRxBuf, cpTcpData);
  206.                         guwEthLen = guwMicRxLen;
  207.                         guwMicRxLen = 0;                // A/D 轉(zhuǎn)換計數(shù)復位
  208.                         SP_OPEN_FIQ();                        // 開啟FIQ中斷,同時也開啟了ADAC
  209.                 } */

  210.                 guwEthLen = 0;
  211.                 gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  212.                 return;

  213.         }


  214.         if (msip_Connected()){
  215.                 gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  216.                 guwEthLen = 0;                        // 釋放TCP數(shù)據(jù)區(qū)
  217.                 /*
  218.                 guwMicRxLen = 0;                // A/D 轉(zhuǎn)換計數(shù)復位
  219.                 guwDAC1TotalLen = 0;        // DAC1 轉(zhuǎn)換計數(shù)復位
  220.                 SP_OPEN_FIQ();                        // 開啟FIQ中斷,同時也開啟了ADAC
  221.                 */

  222.                 return;
  223.         }

  224.         if (msip_Poll()){
  225.                 if (gptConn->PollTime++ > 3*cTCP_MAX_POLL){        // 太長時間空閑(900秒),終止連接!
  226.                                 msip_Close();
  227.                                 //SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC
  228.                 }
  229.                 guwEthLen = 0;
  230.                 return;
  231.         }

  232.         if (msip_Aborted() || msip_Closed()){        // 如果異常關(guān)閉,那就關(guān)閉當前連接
  233.                 //SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC
  234.                 return;
  235.         }

  236. link_adac_active:
  237.         if (msip_Acked()){   // 如果有A/D數(shù)據(jù)要發(fā)送,就轉(zhuǎn)發(fā)TCP數(shù)據(jù)包
  238.                 /*
  239.                 if (guwMicRxLen > 0) {        // 根據(jù)guwMicRxLen判斷是否轉(zhuǎn)發(fā)Audio數(shù)據(jù)
  240.                         SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC
  241.                         MEMCPY(guwMicRxLen, guwMicRxBuf, cpTcpData);
  242.                         guwEthLen = guwMicRxLen;
  243.                         guwMicRxLen = 0;                // A/D 轉(zhuǎn)換計數(shù)復位
  244.                         SP_OPEN_FIQ();                        // 開啟FIQ中斷,同時也開啟了ADAC
  245.                         gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  246.                 } */
  247.                 guwEthLen = 0;
  248.                 return;
  249.         }


  250.         if (msip_NewData()){
  251.                 /*
  252.                 if (guwEthLen > 0){        // 收到Audio數(shù)據(jù)包
  253.                          // 如果上次沒有轉(zhuǎn)換完,就等....
  254.                         while(guwDAC1TxLen < guwDAC1TotalLen);
  255.                         // 如果轉(zhuǎn)換完,就復制buffer
  256.                         SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC
  257.                         if (guwEthLen > cDAC1_MAXLEN){  // 攔截超長bytes部分
  258.                                 guwEthLen = cDAC1_MAXLEN;
  259.                         }
  260.                         MEMCPY(guwEthLen, cpTcpData, guwDAC1TxBuf); // 將TCP數(shù)據(jù)Audio復制給DAC1的buffer
  261.                         guwDAC1TxLen = 0;                           // DAC1 轉(zhuǎn)換計數(shù)復位
  262.                         guwDAC1TotalLen = guwEthLen;        // DAC1 轉(zhuǎn)換buffer總長
  263.                         SP_OPEN_FIQ();                                        // 開啟FIQ中斷,同時也開啟了ADAC

  264.                         guwEthLen = 0;
  265.                 }
  266.                 if (guwMicRxLen > 0) {        // 根據(jù)guwMicRxLen判斷是否轉(zhuǎn)發(fā)Audio數(shù)據(jù)
  267.                         SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC
  268.                         MEMCPY(guwMicRxLen, guwMicRxBuf, cpTcpData);
  269.                         guwEthLen = guwMicRxLen;
  270.                         guwMicRxLen = 0;                // A/D 轉(zhuǎn)換計數(shù)復位
  271.                         SP_OPEN_FIQ();                        // 開啟FIQ中斷,同時也開啟了ADAC
  272.                 } */

  273.                 guwEthLen = 0;
  274.                 gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  275.                 return;

  276.         }


  277.         if (msip_Connected()){
  278.                 gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  279.                 guwEthLen = 0;                        // 釋放TCP數(shù)據(jù)區(qū)
  280.                 /*
  281.                 guwMicRxLen = 0;                // A/D 轉(zhuǎn)換計數(shù)復位
  282.                 guwDAC1TotalLen = 0;        // DAC1 轉(zhuǎn)換計數(shù)復位
  283.                 SP_OPEN_FIQ();                        // 開啟FIQ中斷,同時也開啟了ADAC
  284.                 */

  285.                 return;
  286.         }

  287.         if (msip_Poll()){
  288.                 if (gptConn->PollTime++ > 3*cTCP_MAX_POLL){        // 太長時間空閑(900秒),終止連接!
  289.                                 msip_Close();
  290.                                 //SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC
  291.                 }
  292.                 guwEthLen = 1460;
  293.                 return;
  294.         }

  295.         if (msip_Aborted() || msip_Closed()){        // 如果異常關(guān)閉,那就關(guān)閉當前連接
  296.                 //SP_CLOSE_FIQ();                // 關(guān)閉FIQ中斷,同時也禁止了ADAC
  297.                 return;
  298.         }


  299.         return;
  300. #endif





  301. // 以下部分用于Ping功能失效時的網(wǎng)絡(luò)測試!TMD現(xiàn)在網(wǎng)絡(luò)病毒太多,許多ISP運營商都禁Ping了!
  302. // 不管是否傳數(shù)據(jù),都將在300秒后斷開.....
  303. test_net:

  304.         if (msip_NewData()){
  305.                 // Message: 收到!別惹我,煩著呢......
  306.                 cpTcpData[0] = 0xcad5;
  307.                 cpTcpData[1] = 0xb5bd;
  308.                 cpTcpData[2] = 0xa3a1;
  309.                 cpTcpData[3] = 0xb1f0;
  310.                 cpTcpData[4] = 0xc8c7;
  311.                 cpTcpData[5] = 0xced2;
  312.                 cpTcpData[6] = 0xb7b3;
  313.                 cpTcpData[7] = 0xb7b1;
  314.                 cpTcpData[8] = 0xd7c5;
  315.                 cpTcpData[9] = 0xc4d8;
  316.                 cpTcpData[10] = 0x2e2e;
  317.                 cpTcpData[11] = 0x2e2e;
  318.                 cpTcpData[12] = 0x2e2e;
  319.                 guwEthLen = 26;
  320.                 return;
  321.         }

  322.         if (msip_Poll()){
  323.                 if (gptConn->PollTime == 0){
  324.                         // Message: Welcome to you!
  325.                         cpTcpData[0] = 0x5765;        // "We"+
  326.                         cpTcpData[1] = 0x6c63;        // "lc"+
  327.                         cpTcpData[2] = 0x6f6d;        // "om"+
  328.                         cpTcpData[3] = 0x6520;        // "e "+
  329.                         cpTcpData[4] = 0x746f;        // "to"+
  330.                         cpTcpData[5] = 0x2079;        // "yo"+
  331.                         cpTcpData[6] = 0x6f75;        // " u"+
  332.                         cpTcpData[7] = 0x2120;        // "! "
  333.                         guwEthLen = 16;
  334.                 }

  335.                 if (gptConn->PollTime++ > cTCP_MAX_POLL){        // 太長時間空閑,終止連接!
  336.                         msip_Close();
  337.                 }

  338.                 return;
  339.         }


  340.         if (msip_Connected()){
  341.                 gptConn->PollTime = 0;        // 清除空閑時間記數(shù)
  342.                 return;
  343.         }

  344. //        if (msip_Aborted() || msip_Closed()){        // 如果異常關(guān)閉,那就關(guān)閉當前連接
  345.                 // Nothing to do!
  346. //                return;
  347. //        }

  348.         return;
  349. }
復制代碼




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表