|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2014-6-24 15:57:26
|
显示全部楼层
我是用TCP做的 没有用socket函数,只要没连接上,tcp_err函数会打印错误状态 ERR_ABRT和ERR_RST,然后就执行tcp_close,在这个函数里会释放内存的,
代码流程比较简单的,应该很好看明白
/***********************************************************************
函数名称:client_data_process(void)
功 能:客户端数据处理函数
***********************************************************************/
//client_data_process函数放在主循环while(1)里,系统tick每隔250ms调取一次,
void client_data_process(void)
{
const char content[] = "Hello, PC!\r\n";
//client_err==0 未初始化成功; client_err == 1 连接错误; client_err==2 初始化成功;
if(client_err < 2)
{
use_err++;
if(use_err > 12)//客户端如果不能正常初始化,每隔250ms*12=3秒重新初始化
{
use_err=0;
tcp_client_init();
//led_on(1);
UART0_SendString("Retry connect every 3s\r\n",sizeof("Retry connect every 3s\r\n"));
}
}
else if(client_err == 2)//客户端正常连接,每隔250ms*4=1s向PC服务器发送数据
{
Send_Time++;
/*if((client_pcb->state == ESTABLISHED) && (Send_Time>=4))
{
//tcp_write(client_pcb, content, sizeof(content), TCP_WRITE_FLAG_COPY);
UART0_SendString("Hello, PC!\r\n",sizeof("Hello, PC!\r\n"));
//led_on(2);
Send_Time = 0;
}*/
if(Send_Time>=4)//每隔1秒钟打印一次client pcb的状态
{
switch(client_pcb->state)
{
case CLOSED: UART0_SendStr("0 CLOSED\r\n"); break;
case LISTEN: UART0_SendStr("1 LISTEN\r\n"); break;
case SYN_SENT: UART0_SendStr("2 SYN_SENT\r\n"); break;
case SYN_RCVD: UART0_SendStr("3 SYN_RCVD\r\n"); break;
case ESTABLISHED: UART0_SendStr("4 ESTABLISHED\r\n");break;
case FIN_WAIT_1: UART0_SendStr("5 FIN_WAIT_1\r\n"); break;
case FIN_WAIT_2: UART0_SendStr("6 FIN_WAIT_2\r\n"); break;
case CLOSE_WAIT: UART0_SendStr("7 CLOSE_WAIT\r\n"); break;
case CLOSING: UART0_SendStr("8 CLOSING\r\n"); break;
case LAST_ACK: UART0_SendStr("9 LAST_ACK\r\n"); break;
case TIME_WAIT: UART0_SendStr("10 TIME_WAIT\r\n"); break;
}
tcp_write(client_pcb, content, sizeof(content), TCP_WRITE_FLAG_COPY);
UART0_SendString("Hello, PC!\r\n",sizeof("Hello, PC!\r\n"));
//led_on(2);
Send_Time = 0;
}
}
}
/***********************************************************************
函数名称:static void tcp_client_err(void *arg, err_t err)
功 能:连接错误时处理的回调函数
***********************************************************************/
static void tcp_client_err(void *arg, err_t err)
{
switch(err)
{
case ERR_OK: UART0_SendStr("0 ERR_OK\r\n"); break;
case ERR_MEM: UART0_SendStr("-1 ERR_MEM\r\n"); break;
case ERR_BUF: UART0_SendStr("-2 ERR_BUF\r\n"); break;
case ERR_TIMEOUT: UART0_SendStr("-3 ERR_TIMEOUT\r\n"); tcp_close(client_pcb); client_err=1;break;
case ERR_RTE: UART0_SendStr("-4 ERR_RTE\r\n"); break;
case ERR_ABRT: UART0_SendStr("-5 ERR_ABRT\r\n"); tcp_close(client_pcb); client_err=1; break;
case ERR_RST: UART0_SendStr("-6 ERR_RST\r\n"); tcp_close(client_pcb); client_err=1; break;
case ERR_CLSD: UART0_SendStr("-7 ERR_CLSD\r\n"); tcp_close(client_pcb); client_err=0; break;
case ERR_CONN: UART0_SendStr("-8 ERR_CONN\r\n"); tcp_close(client_pcb); client_err=0; break;
case ERR_VAL: UART0_SendStr("-9 ERR_VAL\r\n"); break;
case ERR_ARG: UART0_SendStr("-10 ERR_ARG\r\n"); break;
case ERR_USE: UART0_SendStr("-11 ERR_USE\r\n"); break;
case ERR_IF: UART0_SendStr("-12 ERR_IF\r\n"); break;
case ERR_ISCONN: UART0_SendStr("-13 ERR_ISCONN\r\n");break;
case ERR_INPROGRESS: UART0_SendStr("-14 ERR_INPROGRESS\r\n");break;
}
switch(client_pcb->state)
{
case CLOSED: UART0_SendStr("0 CLOSED\r\n"); tcp_close(client_pcb); client_err=0; break;
case LISTEN: UART0_SendStr("1 LISTEN\r\n"); break;
case SYN_SENT: UART0_SendStr("2 SYN_SENT\r\n"); break;
case SYN_RCVD: UART0_SendStr("3 SYN_RCVD\r\n"); break;
case ESTABLISHED: UART0_SendStr("4 ESTABLISHED\r\n");break;
case FIN_WAIT_1: UART0_SendStr("5 FIN_WAIT_1\r\n"); break;
case FIN_WAIT_2: UART0_SendStr("6 FIN_WAIT_2\r\n"); break;
case CLOSE_WAIT: UART0_SendStr("7 CLOSE_WAIT\r\n"); break;
case CLOSING: UART0_SendStr("8 CLOSING\r\n"); break;
case LAST_ACK: UART0_SendStr("9 LAST_ACK\r\n"); break;
case TIME_WAIT: UART0_SendStr("10 TIME_WAIT\r\n"); break;
}
}
void tcp_client_init(void)
{
struct ip_addr DestIPaddr;
client_err = 0;//只要进入初始化重新清零
client_pcb = tcp_new();
if (client_pcb != NULL)
{
IP4_ADDR( &DestIPaddr, 10, 16, 4, 26 );//写远程服务器IP
tcp_bind(client_pcb, IP_ADDR_ANY, 4080);//绑定开发板IP和端口号 客户端的端口号随机,也可不配置
if(tcp_connect(client_pcb,&DestIPaddr,8080,tcp_client_connected) == ERR_OK)
{
UART0_SendStr("client_err = 2\r\n");
UART0_SendString("The tcp_client_init OK\r\n",sizeof("The tcp_client_init OK\r\n"));
}
else
{
client_err = 0;//未初始化成功
UART0_SendString("The tcp_client_init not OK\r\n",sizeof("The tcp_client_init not OK\r\n"));
}
tcp_err(client_pcb, tcp_client_err);
}
}
static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
{
struct client *es = NULL;
const char content[] = "This is Tcp_Client\r\n";
if (err == ERR_OK)
{
client_err = 2;//初始化成功,进入了回调函数
es = (struct client *)mem_malloc(sizeof(struct client));
if (es != NULL)
{
es->state = ES_CONNECTED;
es->pcb = tpcb;
es->p_tx = pbuf_alloc(PBUF_TRANSPORT, strlen((char*)data) , PBUF_POOL);
if (es->p_tx)
{
pbuf_take(es->p_tx, (char*)data, strlen((char*)data));
tcp_arg(tpcb, es);
tcp_recv(tpcb, tcp_client_recv);
tcp_poll(tpcb, tcp_client_poll, 1);
UART0_SendString("This is Tcp_Client\r\n",sizeof("This is Tcp_Client\r\n"));
tcp_write(tpcb, content, sizeof(content), TCP_WRITE_FLAG_COPY);
tcp_err(tpcb, tcp_client_err);
return ERR_OK;
}
}
else
{
/* close connection */
tcp_client_connection_close(tpcb, es);
client_err=1;
/* return memory allocation error */
return ERR_MEM;
}
}
else
{
/* close connection */
tcp_client_connection_close(tpcb, es);
client_err=1;
}
return err;
} |
|