TCP client 连接电脑起的Server
Server主动下发4000多字节数据,client收到后返还给server
然后关闭server,此时client打印disconnect
电脑再次打开server client会一直提示timeout 大概2分钟后连接成功
请问这种情况需要如何处理?
TCP client 连接电脑起的Server
Server主动下发4000多字节数据,client收到后返还给server
然后关闭server,此时client打印disconnect
电脑再次打开server client会一直提示timeout 大概2分钟后连接成功
请问这种情况需要如何处理?
看下芯片这边的打印状态,是不是卡在什么状态异常里面了。
#include "ETH.h"
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
#include "CH57xNET.h"
#include "uart.h"
#define KEEPLIVE_ENABLE 1 /* 开启KEEPLIVE功能 */
/* 下面的缓冲区和全局变量必须要定义,库中调用 */
__align(16)UINT8 CH57xMACRxDesBuf[(RX_QUEUE_ENTRIES )*16]; /* MAC接收描述符缓冲区,16字节对齐 */
__align(4) UINT8 CH57xMACRxBuf[RX_QUEUE_ENTRIES*RX_BUF_SIZE]; /* MAC接收缓冲区,4字节对齐 */
__align(4) SOCK_INF SocketInf[CH57xNET_MAX_SOCKET_NUM]; /* Socket信息表,4字节对齐 */
UINT16 MemNum[8] = {CH57xNET_NUM_IPRAW,
CH57xNET_NUM_UDP,
CH57xNET_NUM_TCP,
CH57xNET_NUM_TCP_LISTEN,
CH57xNET_NUM_TCP_SEG,
CH57xNET_NUM_IP_REASSDATA,
CH57xNET_NUM_PBUF,
CH57xNET_NUM_POOL_BUF
};
UINT16 MemSize[8] = {CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IPRAW_PCB),
CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_UDP_PCB),
CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB),
CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB_LISTEN),
CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_SEG),
CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IP_REASSDATA),
CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(0),
CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_POOL_BUF)
};
__align(4)UINT8 Memp_Memory[CH57xNET_MEMP_SIZE];
__align(4)UINT8 Mem_Heap_Memory[CH57xNET_RAM_HEAP_SIZE];
__align(4)UINT8 Mem_ArpTable[CH57xNET_RAM_ARP_TABLE_SIZE];
/******************************************************************************/
/* 本演示程序的相关宏 */
#define RECE_BUF_LEN 536 /* 接收缓冲区的大小 */
/* CH57xNET库TCP的MSS长度为536字节,即一个TCP包里的数据部分最长为536字节 */
/* TCP协议栈采用滑动窗口进行流控,窗口最大值为socket的接收缓冲区长度。在设定 */
/* RX_QUEUE_ENTRIES时要考虑MSS和窗口之间的关系,例如窗口值为4*MSS,则远端一次会发送 */
/* 4个TCP包,如果RX_QUEUE_ENTRIES小于4,则必然会导致数据包丢失,从而导致通讯效率降低 */
/* 建议RX_QUEUE_ENTRIES要大于( 窗口/MSS ),如果多个socket同时进行大批量发送数据,则 */
/* 建议RX_QUEUE_ENTRIES要大于(( 窗口/MSS )*socket个数) 在多个socket同时进行大批数据收发时 */
/* 为了节约RAM,请将接收缓冲区的长度设置为MSS */
/* CH579相关定义 */
UINT8 MACAddr[6] = {0x84,0xc2,0xe4,0x02,0x03,0x04}; /* CH579MAC地址 */
UINT8 IPAddr[4] = {192,168,1,200}; /* CH579IP地址 */
UINT8 GWIPAddr[4] = {192,168,1,1}; /* CH579网关 */
UINT8 IPMask[4] = {255,255,255,0}; /* CH579子网掩码 */
//UINT8 ServerIP[4] = {183,11,220,164};
UINT8 ServerIP[4] = {192,168,10,3};
/* 网口灯定义 PB口低十六位有效 */
UINT16 CH57xNET_LEDCONN=0x0010; /* 连接指示灯 PB4 */
UINT16 CH57xNET_LEDDATA=0x0080; /* 通讯指示灯 PB7 */
UINT8 SocketId; /* 保存socket索引,可以不用定义 */
UINT8 SocketRecvBuf[RECE_BUF_LEN]; /* socket接收缓冲区 */
UINT8 MyBuf[RECE_BUF_LEN]; /* 定义一个临时缓冲区 */
BOOL TCP_Connect_Status = FALSE;
void ETH_Task(void *pdata);
static TimerHandle_t ETH_Timer = NULL;
void ETH_IRQHandler( void ) /* 以太网中断 */
{
CH57xNET_ETHIsr(); /* 以太网中断中断服务函数 */
}
void ETH_Timer_callback(void *pdata)
{
(void)pdata;
CH57xNET_TimeIsr(CH57xNETTIMEPERIOD);
}
/*******************************************************************************
* Function Name : CH57xNET_CreatTcpSocket
* Description : 创建TCP Client socket
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void CH57xNET_CreatTcpSocket(char* ip,int port)
{
UINT8 ret;
SOCK_INF TmpSocketInf; /* 创建临时socket变量 */
memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF)); /* 库内部会将此变量复制,所以最好将临时变量先全部清零 */
memcpy((void *)TmpSocketInf.IPAddr,ip,4); /* 设置目的IP地址 */
TmpSocketInf.DesPort = port;
TmpSocketInf.SourPort = 2000; /* 设置源端口 */
TmpSocketInf.ProtoType = PROTO_TYPE_TCP; /* 设置socekt类型 */
TmpSocketInf.RecvStartPoint = (UINT32)SocketRecvBuf; /* 设置接收缓冲区的接收缓冲区 */
TmpSocketInf.RecvBufLen = RECE_BUF_LEN ; /* 设置接收缓冲区的接收长度 */
ret = CH57xNET_SocketCreat(&SocketId,&TmpSocketInf); /* 创建socket,将返回的socket索引保存在SocketId中 */
APP_DEBUG("CH57xNET_SocketCreat:%s",(ret == CH57xNET_ERR_SUCCESS)?"OK":"ERROR");
#ifdef KEEPLIVE_ENABLE
//CH57xNET_SocketSetKeepLive( SocketId, 1 ); /* 开启socket的KEEPLIVE功能(V06版本支持) */
#endif
ret = CH57xNET_SocketConnect(SocketId); /* TCP连接 */
APP_DEBUG("CH57xNET_SocketConnect:%s",(ret == CH57xNET_ERR_SUCCESS)?"OK":"ERROR");
//ret = CH57xNET_SetSocketTTL( SocketId,128 );
//APP_DEBUG("CH57xNET_SetSocketTTL:%s",(ret == CH57xNET_ERR_SUCCESS)?"OK":"ERROR");
}
/*******************************************************************************
* Function Name : CH57xNET_HandleSockInt
* Description : Socket中断处理函数
* Input : sockeid socket索引
* :initstat 中断状态
* Output : None
* Return : None
*******************************************************************************/
void CH57xNET_HandleSockInt(UINT8 sockeid,UINT8 initstat)
{
UINT32 len;
// UINT32 totallen;
UINT8 *p = MyBuf;
if(initstat & SINT_STAT_RECV) /* 接收中断 */
{
len = CH57xNET_SocketRecvLen(sockeid,NULL); /* 查询长度 */
APP_DEBUG("Receive Len = %d",len);
// totallen = len;
CH57xNET_SocketRecv(sockeid,MyBuf,&len); /* 将接收缓冲区的数据读到MyBuf中*/
CH57xNET_SocketSend(sockeid,p,&len);
// while(1)
// {
// len = totallen;
// CH57xNET_SocketSend(sockeid,p,&len); /* 将MyBuf中的数据发送 */
// totallen -= len; /* 将总长度减去以及发送完毕的长度 */
// p += len; /* 将缓冲区指针偏移*/
// if(totallen)continue; /* 如果数据未发送完毕,则继续发送*/
// break; /* 发送完毕,退出 */
// }
}
if(initstat & SINT_STAT_CONNECT) /* TCP连接中断 */
{ /* 产生此中断表示TCP已经连接,可以进行收发数据 */
APP_DEBUG("TCP Connect Success");
}
if(initstat & SINT_STAT_DISCONNECT) /* TCP断开中断 */
{ /* 产生此中断,CH579库内部会将此socket清除,置为关闭*/
APP_DEBUG("TCP Disconnect:%d",SocketId);
TCP_Connect_Status = TRUE;
}
if(initstat & SINT_STAT_TIM_OUT) /* TCP超时中断 */
{ /* 产生此中断,CH579库内部会将此socket清除,置为关闭*/
APP_DEBUG("TCP Connect Timout");
TCP_Connect_Status = TRUE;
}
}
UINT8 CH57xNET_DHCPCallBack(UINT8 status,void *arg)
{
UINT8 *p;
if(!status){ /* 成功*/
p = arg; /* 产生此中断,CH57xNET库内部会将此socket清除,置为关闭*/
APP_DEBUG("DHCP Success");
memcpy(IPAddr,p,4);
memcpy(GWIPAddr,&p[4],4);
memcpy(IPMask,&p[8],4); /* 产生此中断,CH57xNET库内部会将此socket清除,置为关闭*/
APP_DEBUG("IPAddr = %d.%d.%d.%d",(UINT16)IPAddr[0],(UINT16)IPAddr[1],
(UINT16)IPAddr[2],(UINT16)IPAddr[3]);
APP_DEBUG("GWIPAddr = %d.%d.%d.%d",(UINT16)GWIPAddr[0],(UINT16)GWIPAddr[1],
(UINT16)GWIPAddr[2],(UINT16)GWIPAddr[3]);
APP_DEBUG("IPAddr = %d.%d.%d.%d",(UINT16)IPMask[0],(UINT16)IPMask[1],
(UINT16)IPMask[2],(UINT16)IPMask[3]);
APP_DEBUG("DNS1: %d.%d.%d.%d",p[12],p[13],p[14],p[15]);
APP_DEBUG("DNS2: %d.%d.%d.%d",p[16],p[17],p[18],p[19]);
TCP_Connect_Status = TRUE;
}
else{
/* 产生此中断,CH57xNET库内部会将此socket清除,置为关闭*/
APP_DEBUG("DHCP Fail %02x\n",status);
}
return 0;
}
/*******************************************************************************
* Function Name : CH57xNET_HandleGloableInt
* Description : 全局中断处理函数
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void CH57xNET_HandleGlobalInt(void)
{
UINT8 initstat;
UINT8 i;
UINT8 socketinit;
initstat = CH57xNET_GetGlobalInt(); /* 读全局中断状态并清除 */
if(initstat & GINT_STAT_UNREACH) /* 不可达中断 */
{
APP_DEBUG("UnreachCode :%d",CH57xInf.UnreachCode); /* 查看不可达代码 */
APP_DEBUG("UnreachProto :%d",CH57xInf.UnreachProto); /* 查看不可达协议类型 */
APP_DEBUG("UnreachPort :%d",CH57xInf.UnreachPort); /* 查询不可达端口 */
}
if(initstat & GINT_STAT_IP_CONFLI) /* IP冲突中断 */
{
}
if(initstat & GINT_STAT_PHY_CHANGE) /* PHY改变中断 */
{
i = CH57xNET_GetPHYStatus(); /* 获取PHY状态 */
if(i > 1)
{
CH57xNET_DHCPStart(CH57xNET_DHCPCallBack);
}
else
{
CH57xNET_DHCPStop();
}
APP_DEBUG("GINT_STAT_PHY_CHANGE %02x",i);
}
if(initstat & GINT_STAT_SOCKET) /* Socket中断 */
{
for(i = 0; i < CH57xNET_MAX_SOCKET_NUM; i ++)
{
socketinit = CH57xNET_GetSocketInt(i); /* 读socket中断并清零 */
if(socketinit)
{
CH57xNET_HandleSockInt(i,socketinit); /* 如果有中断则清零 */
}
}
}
}
void net_initkeeplive(void)
{
struct _KEEP_CFG klcfg;
klcfg.KLIdle = 10000; /* 空闲 */
klcfg.KLIntvl = 10000; /* 间隔 */
klcfg.KLCount = 2; /* 次数 */
CH57xNET_ConfigKeepLive(&klcfg);
}
void Bsp_ETH_init(void)
{
char ret = 0;
struct _CH57x_CFG cfg;
if(CH57xNET_GetVer() != CH57xNET_LIB_VER)return; /* 获取库的版本号,检查是否和头文件一致 */
CH57xNETConfig = LIB_CFG_VALUE; /* 将配置信息传递给库的配置变量 */
cfg.RxBufSize = RX_BUF_SIZE;
cfg.TCPMss = CH57xNET_TCP_MSS;
cfg.HeapSize = CH57x_MEM_HEAP_SIZE;
cfg.ARPTableNum = CH57xNET_NUM_ARP_TABLE;
cfg.MiscConfig0 = CH57xNET_MISC_CONFIG0;
CH57xNET_ConfigLIB(&cfg);
ret = CH57xNET_Init(IPAddr,GWIPAddr,IPMask,MACAddr);
net_initkeeplive();
APP_DEBUG("CH57xNET_Init:%s",(ret == CH57xNET_ERR_SUCCESS)?"OK":"ERROR");
if(ret == CH57xNET_ERR_SUCCESS)
{
ETH_Timer = xTimerCreate("ETH_Timer",10,pdTRUE,(void*)0,ETH_Timer_callback);
if(ETH_Timer != NULL)
{
xTimerStart(ETH_Timer,10);
}
xTaskCreate(ETH_Task, "ETH_Task", 1024, NULL, 1, NULL );
}
NVIC_EnableIRQ(ETH_IRQn);
}
void ETH_Task(void *pdata)
{
(void)pdata;
vTaskDelay(100);
while(1)
{
CH57xNET_MainTask();
if(CH57xNET_QueryGlobalInt())
{
CH57xNET_HandleGlobalInt();
}
if(TCP_Connect_Status == TRUE)
{
TCP_Connect_Status = FALSE;
CH57xNET_CreatTcpSocket((char*)ServerIP,8080);
}
vTaskDelay(1);
}
}