標(biāo)題:
嵌入式的TCP+IP協(xié)議的完整C源程序
[打印本頁(yè)]
作者:
阿凡達(dá)特
時(shí)間:
2017-9-14 10:44
標(biāo)題:
嵌入式的TCP+IP協(xié)議的完整C源程序
做一個(gè)項(xiàng)目涉及到的tcp/ip 源代碼
0.png
(44.48 KB, 下載次數(shù): 52)
下載附件
2017-9-14 16:21 上傳
所有資料51hei提供下載:
TCP IP協(xié)議的完整C源程序.rar
(26.62 KB, 下載次數(shù): 26)
2017-9-14 10:43 上傳
點(diǎn)擊文件名下載附件
關(guān)于源代碼
下載積分: 黑幣 -5
源程序如下:
// 版權(quán) 2003, 王衛(wèi)無(wú),四川綿陽(yáng)岷山集團(tuán)有限公司--研究開發(fā)中心
// wolver@minshan-inc.com
// 保留一切權(quán)利
//
// 如果符合以下條件,則無(wú)論是以原代碼或非原代碼代碼形式,且不論是否修改,
// 再分發(fā)和使用本軟件都是被允許的。
// 1. 原代碼的再分發(fā)必須保留上述的版權(quán)聲明、本條件說(shuō)明和以下免責(zé)聲明。
// 2. 非原代碼形式的再分發(fā),必須在證明文件和(或)其它一同提供的材料中重新
// 作上述的版權(quán)聲明、本條件說(shuō)明和以下免責(zé)聲明。
// 3. 一切提及本軟件和使用的廣告材料必須顯示以下致謝:
// 本產(chǎn)品包含王衛(wèi)無(wú)(四川綿陽(yáng)岷山集團(tuán)有限公司--研究開發(fā)中心)開發(fā)的軟件。
// 4. 如果沒(méi)有預(yù)先得到特定的書面許可,不能用作者的名字來(lái)宣傳推廣基于本軟件得到
// 的產(chǎn)品。
//
// 免責(zé)聲明:
// 本軟件是由某某作者提供,如果出現(xiàn)以下情況,作者都不承擔(dān)任何責(zé)任。
// 1. 因作者的說(shuō)明以及任何明確的或暗示的保證(包括但不限于表達(dá)某種商業(yè)性和適合某一
// 特定目的暗示性保證)而產(chǎn)生的損失。
// 2. 無(wú)論在何種情況下,對(duì)使用本軟件造成的任何直接的、間接的、偶然的、特定的、可預(yù)
// 見性的和連帶產(chǎn)生的損失(包括但不限于獲取產(chǎn)品和服務(wù)、作用喪失、數(shù)據(jù)遺失、利益損
// 失或商業(yè)干預(yù)),無(wú)論這些損失是怎樣造成的,并且是以何種方式闡釋責(zé)任。
// 3. 任何因使用本軟件而相關(guān)的合同、嚴(yán)格賠償責(zé)任和侵權(quán)行為(包含:疏忽或其它)的損失,
// 甚至即便是可能的此類已經(jīng)明示或暗示的損失。
///
#include "system.h"
#include "tcpip.h"
#include "drivers.h"
// 定義應(yīng)用:1 表示開啟功能,0 表示關(guān)閉功能
#define cTCP_RS232 1 // TCP <-> RS232 的應(yīng)用,只用于服務(wù)模式
#define cTCP_ADAC 1 // TCP <-> Audio, 主要用于服務(wù),也可以用于客戶。要求高帶寬: > 912Kbit
// 分配本地用戶自定義服務(wù)模式應(yīng)用TCP端口號(hào),不能與知名端口相同!如:23, 80
// 注意:對(duì)不同的TCP事件使用不同的本地端口號(hào),有助于快速查找TCP事件而不需要判斷IP是否相同!
// 這樣做能使本地快速響應(yīng)。
#define cTCP_ListenPort_TEST 0x1000 // 4096
#if cTCP_RS232 == 1
#define cTCP_ListenPort_RS232 0x2000 // 8192
#endif
#if cTCP_ADAC == 0
#define cTCP_ListenPort_ADAC 0x3000 // 12288
#endif
// 客戶應(yīng)用模式的本地TCP端口號(hào)。不能與知名端口相同!如:23, 80
// 注意:對(duì)不同的TCP事件使用不同的本地端口號(hào)(包括:本地偵聽端口),有助于快速查找TCP事件而
// 不需要判斷IP是否相同!這樣做能使本地快速響應(yīng)。
#if (cTCP_ADAC == 1) && (TCP_ACTIVE_OPEN == 1)
#define cTCP_ActivePort_ADAC 0x3001 // 12289
#endif
// 分配系統(tǒng)應(yīng)用臨時(shí)緩沖區(qū)(按 wrod 存儲(chǔ))
UINT16 guwAppBuf[cAppSizeMax];
//--------------------------------------------------------------------------------------
main(){
#if TCP_ACTIVE_OPEN == 1
UINT16 temp[2];
#endif
// 1. Hardware initialize: SPCE061A
SP_IO_INIT();
// 2. Open and Enable Hardware interrupt 2Hz and Clear WatchDog!
SP_OpenTime2();
// 3. Hardware initialize: RTL8019AS
RTL8019AS_RESET();
RTL8019AS_INIT();
// 4. vIP4 TCP/IP initialize
msip_Init();
// 5. We listen test port
msip_Listen(cTCP_ListenPort_TEST); // 用于偵聽來(lái)自鏈路測(cè)試的TCP包
#if cTCP_RS232 == 1
SP_UART_INIT(C_UART_Baud_115200); // Hardware initialize: UART of SPCE061A
msip_Listen(cTCP_ListenPort_RS232); // 用于偵聽來(lái)自RS232的TCP包
#endif
#if cTCP_ADAC == 1
// SP_ADAC_INIT(cSample_4096); // Open ADAC
// SP_ADAC_INIT(cSample_8192); // Open ADAC
// SP_ADAC_INIT(cSample_16384); // Open ADAC
// SP_ADAC_INIT(cSample_32768); // Open ADAC
// SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
msip_Listen(cTCP_ListenPort_ADAC); // 用于偵聽來(lái)自遠(yuǎn)端的Audio的TCP包
#endif
#if (cTCP_ADAC == 1) && (TCP_ACTIVE_OPEN == 1)
// for test audio, wo active link remote: 192.168.0.60
temp[0] = ((192<<8)|168);
temp[1] = ((0<<8)|30);
msip_Connect(cTCP_ActivePort_ADAC, temp, cTCP_ListenPort_ADAC);
#endif
// 6. We do TCP/IP Check Loop
loop:
// 接收新的以太包,并處理
if ((guwEthLen = ether_Receive()) != 0){
switch (cptEthHdrBuf->EthType){
case cEthType_Arp:
msip_Arp_In();
break;
case cEthType_Ip:
msip_Input();
}
}
// ARP表老化處理
if (guwMsg_Route & cM_ARP_TIME){
msip_Arp_Time();
}
// TCP事件輪詢
if (guwMsg_Route & cM_TCP_PERIODIC){
msip_Periodic();
}
goto loop;
}
// SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB-SUB
//--------------------------------------------------------------------------------------
//
// |--------------| |-----|----------|------| |------|--------|
// |工業(yè)設(shè)備|RS232| <---> |RS232|核心嵌入板|TCP/IP| <---> |TCP/IP|普通PC機(jī)|
// |--------------| |-----|----------|------| |------|--------|
//
//-------------------------------------------------------------------------------------
void userapp(){
switch (gptConn->LocalPort){
#if cTCP_RS232 == 1
case cTCP_ListenPort_RS232:
goto link_rs232;
#endif
#if cTCP_ADAC == 1 // ADAC 工作時(shí):由于雙向通訊,所以Listen和Active處理是一樣的!
case cTCP_ListenPort_ADAC:
goto link_adac_listen;
#endif
#if (cTCP_ADAC == 1) && (TCP_ACTIVE_OPEN == 1) // ADAC 工作時(shí):由于雙向通訊,所以Listen和Active處理是一樣的!
case cTCP_ActivePort_ADAC:
goto link_adac_active;
#endif
case cTCP_ListenPort_TEST:
goto test_net;
default:
return;
}
#if cTCP_RS232 == 1
link_rs232: // 與RS232透明傳輸通訊:本系統(tǒng)的一個(gè)應(yīng)用。
// 以下事件的過(guò)慮判斷并不按照事件發(fā)生的順序,是因?yàn)橛行┦录ǔV粫?huì)發(fā)生一次,
// 從而在大多數(shù)其它經(jīng)常發(fā)生的事件狀態(tài)下,減少對(duì)那些事件的過(guò)濾判斷,以提高速度!!!
if (msip_Poll() || msip_Acked()){ // 如果RS232有數(shù)據(jù)要發(fā)送,就轉(zhuǎn)發(fā)TCP數(shù)據(jù)段!
if (guwUartRxLen > 0) { // 根據(jù)guwUartRxLen判斷是否轉(zhuǎn)發(fā)RS232數(shù)據(jù)
MEMCPY(guwUartRxLen, guwUartRxBuf, cpTcpData);
guwEthLen = guwUartRxLen;
guwUartRxLen = 0;
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
} else if (gptConn->PollTime++ > 3*cTCP_MAX_POLL){ // 太長(zhǎng)時(shí)間空閑(900秒),終止連接!
msip_Close();
}
return;
}
if (msip_NewData()){ // 收到TCP數(shù)據(jù)包,轉(zhuǎn)發(fā)給RS232
if (guwEthLen > 0){
SP_UART_TX(guwEthLen, cpTcpData);
guwEthLen = 0;
}
if (guwUartRxLen > 0) { // 根據(jù)guwUartRxLen判斷是否轉(zhuǎn)發(fā)RS232數(shù)據(jù)
MEMCPY(guwUartRxLen, guwUartRxBuf, cpTcpData);
guwEthLen = guwUartRxLen;
guwUartRxLen = 0;
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
}
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
return;
}
if (msip_Connected()){
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
guwEthLen = 0; // 釋放TCP數(shù)據(jù)區(qū)
return;
}
// if (msip_Aborted() || msip_Closed()){ // 如果異常關(guān)閉,那就關(guān)閉當(dāng)前連接
// Nothing to do!
// return;
// }
return;
#endif
#if cTCP_ADAC == 1 // ADAC 工作時(shí):由于雙向通訊,所以Listen和Active處理是一樣的!
link_adac_listen:
if (msip_Acked()){ // 如果有A/D數(shù)據(jù)要發(fā)送,就轉(zhuǎn)發(fā)TCP數(shù)據(jù)包
/*
if (guwMicRxLen > 0) { // 根據(jù)guwMicRxLen判斷是否轉(zhuǎn)發(fā)Audio數(shù)據(jù)
SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
MEMCPY(guwMicRxLen, guwMicRxBuf, cpTcpData);
guwEthLen = guwMicRxLen;
guwMicRxLen = 0; // A/D 轉(zhuǎn)換計(jì)數(shù)復(fù)位
SP_OPEN_FIQ(); // 開啟FIQ中斷,同時(shí)也開啟了ADAC
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
} */
guwEthLen = 0;
return;
}
if (msip_NewData()){
/*
if (guwEthLen > 0){ // 收到Audio數(shù)據(jù)包
// 如果上次沒(méi)有轉(zhuǎn)換完,就等....
while(guwDAC1TxLen < guwDAC1TotalLen);
// 如果轉(zhuǎn)換完,就復(fù)制buffer
SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
if (guwEthLen > cDAC1_MAXLEN){ // 攔截超長(zhǎng)bytes部分
guwEthLen = cDAC1_MAXLEN;
}
MEMCPY(guwEthLen, cpTcpData, guwDAC1TxBuf); // 將TCP數(shù)據(jù)Audio復(fù)制給DAC1的buffer
guwDAC1TxLen = 0; // DAC1 轉(zhuǎn)換計(jì)數(shù)復(fù)位
guwDAC1TotalLen = guwEthLen; // DAC1 轉(zhuǎn)換buffer總長(zhǎng)
SP_OPEN_FIQ(); // 開啟FIQ中斷,同時(shí)也開啟了ADAC
guwEthLen = 0;
}
if (guwMicRxLen > 0) { // 根據(jù)guwMicRxLen判斷是否轉(zhuǎn)發(fā)Audio數(shù)據(jù)
SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
MEMCPY(guwMicRxLen, guwMicRxBuf, cpTcpData);
guwEthLen = guwMicRxLen;
guwMicRxLen = 0; // A/D 轉(zhuǎn)換計(jì)數(shù)復(fù)位
SP_OPEN_FIQ(); // 開啟FIQ中斷,同時(shí)也開啟了ADAC
} */
guwEthLen = 0;
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
return;
}
if (msip_Connected()){
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
guwEthLen = 0; // 釋放TCP數(shù)據(jù)區(qū)
/*
guwMicRxLen = 0; // A/D 轉(zhuǎn)換計(jì)數(shù)復(fù)位
guwDAC1TotalLen = 0; // DAC1 轉(zhuǎn)換計(jì)數(shù)復(fù)位
SP_OPEN_FIQ(); // 開啟FIQ中斷,同時(shí)也開啟了ADAC
*/
return;
}
if (msip_Poll()){
if (gptConn->PollTime++ > 3*cTCP_MAX_POLL){ // 太長(zhǎng)時(shí)間空閑(900秒),終止連接!
msip_Close();
//SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
}
guwEthLen = 0;
return;
}
if (msip_Aborted() || msip_Closed()){ // 如果異常關(guān)閉,那就關(guān)閉當(dāng)前連接
//SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
return;
}
link_adac_active:
if (msip_Acked()){ // 如果有A/D數(shù)據(jù)要發(fā)送,就轉(zhuǎn)發(fā)TCP數(shù)據(jù)包
/*
if (guwMicRxLen > 0) { // 根據(jù)guwMicRxLen判斷是否轉(zhuǎn)發(fā)Audio數(shù)據(jù)
SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
MEMCPY(guwMicRxLen, guwMicRxBuf, cpTcpData);
guwEthLen = guwMicRxLen;
guwMicRxLen = 0; // A/D 轉(zhuǎn)換計(jì)數(shù)復(fù)位
SP_OPEN_FIQ(); // 開啟FIQ中斷,同時(shí)也開啟了ADAC
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
} */
guwEthLen = 0;
return;
}
if (msip_NewData()){
/*
if (guwEthLen > 0){ // 收到Audio數(shù)據(jù)包
// 如果上次沒(méi)有轉(zhuǎn)換完,就等....
while(guwDAC1TxLen < guwDAC1TotalLen);
// 如果轉(zhuǎn)換完,就復(fù)制buffer
SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
if (guwEthLen > cDAC1_MAXLEN){ // 攔截超長(zhǎng)bytes部分
guwEthLen = cDAC1_MAXLEN;
}
MEMCPY(guwEthLen, cpTcpData, guwDAC1TxBuf); // 將TCP數(shù)據(jù)Audio復(fù)制給DAC1的buffer
guwDAC1TxLen = 0; // DAC1 轉(zhuǎn)換計(jì)數(shù)復(fù)位
guwDAC1TotalLen = guwEthLen; // DAC1 轉(zhuǎn)換buffer總長(zhǎng)
SP_OPEN_FIQ(); // 開啟FIQ中斷,同時(shí)也開啟了ADAC
guwEthLen = 0;
}
if (guwMicRxLen > 0) { // 根據(jù)guwMicRxLen判斷是否轉(zhuǎn)發(fā)Audio數(shù)據(jù)
SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
MEMCPY(guwMicRxLen, guwMicRxBuf, cpTcpData);
guwEthLen = guwMicRxLen;
guwMicRxLen = 0; // A/D 轉(zhuǎn)換計(jì)數(shù)復(fù)位
SP_OPEN_FIQ(); // 開啟FIQ中斷,同時(shí)也開啟了ADAC
} */
guwEthLen = 0;
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
return;
}
if (msip_Connected()){
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
guwEthLen = 0; // 釋放TCP數(shù)據(jù)區(qū)
/*
guwMicRxLen = 0; // A/D 轉(zhuǎn)換計(jì)數(shù)復(fù)位
guwDAC1TotalLen = 0; // DAC1 轉(zhuǎn)換計(jì)數(shù)復(fù)位
SP_OPEN_FIQ(); // 開啟FIQ中斷,同時(shí)也開啟了ADAC
*/
return;
}
if (msip_Poll()){
if (gptConn->PollTime++ > 3*cTCP_MAX_POLL){ // 太長(zhǎng)時(shí)間空閑(900秒),終止連接!
msip_Close();
//SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
}
guwEthLen = 1460;
return;
}
if (msip_Aborted() || msip_Closed()){ // 如果異常關(guān)閉,那就關(guān)閉當(dāng)前連接
//SP_CLOSE_FIQ(); // 關(guān)閉FIQ中斷,同時(shí)也禁止了ADAC
return;
}
return;
#endif
// 以下部分用于Ping功能失效時(shí)的網(wǎng)絡(luò)測(cè)試!TMD現(xiàn)在網(wǎng)絡(luò)病毒太多,許多ISP運(yùn)營(yíng)商都禁Ping了!
// 不管是否傳數(shù)據(jù),都將在300秒后斷開.....
test_net:
if (msip_NewData()){
// Message: 收到!別惹我,煩著呢......
cpTcpData[0] = 0xcad5;
cpTcpData[1] = 0xb5bd;
cpTcpData[2] = 0xa3a1;
cpTcpData[3] = 0xb1f0;
cpTcpData[4] = 0xc8c7;
cpTcpData[5] = 0xced2;
cpTcpData[6] = 0xb7b3;
cpTcpData[7] = 0xb7b1;
cpTcpData[8] = 0xd7c5;
cpTcpData[9] = 0xc4d8;
cpTcpData[10] = 0x2e2e;
cpTcpData[11] = 0x2e2e;
cpTcpData[12] = 0x2e2e;
guwEthLen = 26;
return;
}
if (msip_Poll()){
if (gptConn->PollTime == 0){
// Message: Welcome to you!
cpTcpData[0] = 0x5765; // "We"+
cpTcpData[1] = 0x6c63; // "lc"+
cpTcpData[2] = 0x6f6d; // "om"+
cpTcpData[3] = 0x6520; // "e "+
cpTcpData[4] = 0x746f; // "to"+
cpTcpData[5] = 0x2079; // "yo"+
cpTcpData[6] = 0x6f75; // " u"+
cpTcpData[7] = 0x2120; // "! "
guwEthLen = 16;
}
if (gptConn->PollTime++ > cTCP_MAX_POLL){ // 太長(zhǎng)時(shí)間空閑,終止連接!
msip_Close();
}
return;
}
if (msip_Connected()){
gptConn->PollTime = 0; // 清除空閑時(shí)間記數(shù)
return;
}
// if (msip_Aborted() || msip_Closed()){ // 如果異常關(guān)閉,那就關(guān)閉當(dāng)前連接
// Nothing to do!
// return;
// }
return;
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1