[转载]c语⾔实现单⽚机的tcpip通信repost
原⽂地址:c语⾔实现单⽚机的tcp/ip通信作者:谢绝关注
#include "system.h"
#include "tcpip.h"
#include "drivers.h"
// 定义应⽤:1 表⽰开启功能,0 表⽰关闭功能
#define cTCP_RS232 1 // TCP <-> RS232 的应⽤,只⽤于服务模式
#define cTCP_ADAC 1 // TCP <-> Audio, 主要⽤于服务,也可以⽤于客户。要求⾼带宽: > 912Kbit
// 分配本地⽤户⾃定义服务模式应⽤TCP端⼝号,不能与知名端⼝相同!如:23, 80
// 注意:对不同的TCP事件使⽤不同的本地端⼝号,有助于快速查TCP事件⽽不需要判断IP是否相同!// 这样做能使本地快速响应。
#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
// 客户应⽤模式的本地TCP端⼝号。不能与知名端⼝相同!如:23, 80
// 注意:对不同的TCP事件使⽤不同的本地端⼝号(包括:本地侦听端⼝),有助于快速查TCP事件⽽// 不需要判断IP是否相同!这样做能使本地快速响应。
#if (cTCP_ADAC == 1) && (TCP_ACTIVE_OPEN == 1)
#define cTCP_ActivePort_ADAC 0x3001 // 12289
#endif
// 分配系统应⽤临时缓冲区(按 wrod 存储)
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); // ⽤于侦听来⾃链路测试的TCP包
#if cTCP_RS232 == 1
SP_UART_INIT(C_UART_Baud_115200); // Hardware initialize: UART of SPCE061A
msip_Listen(cTCP_ListenPort_RS232); // ⽤于侦听来⾃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(); // 关闭FIQ中断,同时也禁⽌了ADAC
msip_Listen(cTCP_ListenPort_ADAC); // ⽤于侦听来⾃远端的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
//--------------------------------------------------------------------------------------
//
// |--------------| |-----|----------|------| |------|--------|
// |⼯业设备|RS232| <---> |RS232|核⼼嵌⼊板|TCP/IP| <---> |TCP/IP|普通PC机|
// |--------------| |-----|----------|------| |------|--------|
//
//-------------------------------------------------------------------------------------
void userapp(){
switch (gptConn->LocalPort){
#if cTCP_RS232 == 1
case cTCP_ListenPort_RS232:
goto link_rs232;
#endif
#if cTCP_ADAC == 1 // ADAC ⼯作时:由于双向通讯,所以Listen和Active处理是⼀样的!
case cTCP_ListenPort_ADAC:
goto link_adac_listen;
#endif
#if (cTCP_ADAC == 1) && (TCP_ACTIVE_OPEN == 1) // ADAC ⼯作时:由于双向通讯,所以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透明传输通讯:本系统的⼀个应⽤。
// 以下事件的过虑判断并不按照事件发⽣的顺序,是因为有些事件通常只会发⽣⼀次,
/
/ 从⽽在⼤多数其它经常发⽣的事件状态下,减少对那些事件的过滤判断,以提⾼速度
if (msip_Poll() || msip_Acked()){ // 如果RS232有数据要发送,就转发TCP数据段!
if (guwUartRxLen > 0) { // 根据guwUartRxLen判断是否转发RS232数据
MEMCPY(guwUartRxLen, guwUartRxBuf, cpTcpData);
guwEthLen = guwUartRxLen;
guwUartRxLen = 0;
gptConn->PollTime = 0; // 清除空闲时间记数
} else if (gptConn->PollTime++ > 3*cTCP_MAX_POLL){ // 太长时间空闲(900秒),终⽌连接!msip_Close();
}
return;
}
if (msip_NewData()){ // 收到TCP数据包,转发给RS232
if (guwEthLen > 0){
SP_UART_TX(guwEthLen, cpTcpData);
guwEthLen = 0;
}
if (guwUartRxLen > 0) { // 根据guwUartRxLen判断是否转发RS232数据
MEMCPY(guwUartRxLen, guwUartRxBuf, cpTcpData);
guwEthLen = guwUartRxLen;
guwUartRxLen = 0;
gptConn->PollTime = 0; // 清除空闲时间记数
}
gptConn->PollTime = 0; // 清除空闲时间记数
return;
}
if (msip_Connected()){
gptConn->PollTime = 0; // 清除空闲时间记数
guwEthLen = 0; // 释放TCP数据区
return;
}
// if (msip_Aborted() || msip_Closed()){ // 如果异常关闭,那就关闭当前连接
// Nothing to do!
// return;
/
/ }
return;
#endif
#if cTCP_ADAC == 1 // ADAC ⼯作时:由于双向通讯,所以Listen和Active处理是⼀样的!link_adac_listen:
if (msip_Acked()){ // 如果有A/D数据要发送,就转发TCP数据包
guwEthLen = 0;
return;
}
if (msip_NewData()){
guwEthLen = 0;
gptConn->PollTime = 0; // 清除空闲时间记数
return;
}
if (msip_Connected()){
gptConn->PollTime = 0; // 清除空闲时间记数
guwEthLen = 0; // 释放TCP数据区
return;
}
if (msip_Poll()){
if (gptConn->PollTime++ > 3*cTCP_MAX_POLL){ // 太长时间空闲(900秒),终⽌连接!
msip_Close();
//SP_CLOSE_FIQ(); // 关闭FIQ中断,同时也禁⽌了ADAC
}
guwEthLen = 0;
return;
}
if (msip_Aborted() || msip_Closed()){ // 如果异常关闭,那就关闭当前连接
//SP_CLOSE_FIQ(); // 关闭FIQ中断,同时也禁⽌了ADAC
return;
}
link_adac_active:
if (msip_Acked()){ // 如果有A/D数据要发送,就转发TCP数据包
guwEthLen = 0;
return;
}
if (msip_NewData()){
guwEthLen = 0;
gptConn->PollTime = 0; // 清除空闲时间记数
return;
}
if (msip_Connected()){
gptConn->PollTime = 0; // 清除空闲时间记数
guwEthLen = 0; // 释放TCP数据区
return;c tcpip协议
}
if (msip_Poll()){
if (gptConn->PollTime++ > 3*cTCP_MAX_POLL){ // 太长时间空闲(900秒),终⽌连接!
msip_Close();
//SP_CLOSE_FIQ(); // 关闭FIQ中断,同时也禁⽌了ADAC
}
guwEthLen = 1460;
return;
}
if (msip_Aborted() || msip_Closed()){ // 如果异常关闭,那就关闭当前连接
//SP_CLOSE_FIQ(); // 关闭FIQ中断,同时也禁⽌了ADAC
return;
}
return;
#endif
// 以下部分⽤于Ping功能失效时的⽹络测试!TMD现在⽹络病毒太多,许多ISP运营商都禁Ping了!// 不管是否传数据,都将在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){ // 太长时间空闲,终⽌连接!msip_Close();
}
return;
}
if (msip_Connected()){
gptConn->PollTime = 0; // 清除空闲时间记数
return;
}
// if (msip_Aborted() || msip_Closed()){ // 如果异常关闭,那就关闭当前连接
// Nothing to do!
// return;
// }
return;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论