|
发表于 2014-6-25 09:56:10
|
显示全部楼层
本帖最后由 gerbansh520 于 2014-6-25 10:02 编辑
上传不了附件,不知道为什么 多谢。。
/***********************************************************************
函数名称:client_data_process(void)
功 能:客户端数据处理函数
***********************************************************************/
//System_Periodic_Handle函数中调用 client_data_process,系统每隔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_SendByte(0xc1);UART0_SendByte(0xc2);
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))
{
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_SendByte(0xc3);UART0_SendByte(0xc4);
UART0_SendString("Hello, PC!\r\n",sizeof("Hello, PC!\r\n"));
//led_on(2);
Send_Time = 0;
}*/
if(Send_Time>=4)//1秒钟打印一次状态
{
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;
}
}
/**
* @brief Connects to the TCP echo server
* @param None
* @retval None
*/
volatile uint8_t pcb_flag=0;
void tcp_client_init(void)
{
struct ip_addr DestIPaddr;
client_err = 0;//只要进入初始化重新清零
/* create new tcp pcb */
//if(pcb_flag == 0)
//{
client_pcb = tcp_new();
//}
if (client_pcb != NULL)
{
//pcb_flag=1;
IP4_ADDR( &DestIPaddr, 10, 16, 4, 26 );//写远程服务器IP
tcp_bind(client_pcb, IP_ADDR_ANY, 4080);//绑定开发板IP和端口号 客户端的端口号随机
//UART0_SendStr("state2\r\n");
/* connect to destination address/port */
//配置要连接的远程服务器IP地址和端口号,端口号:8080
//tcp_connect(client_pcb,&DestIPaddr,8080,tcp_client_connected);
if(tcp_connect(client_pcb,&DestIPaddr,8080,tcp_client_connected) == ERR_OK)
{
//client_pcb->so_options |= SOF_KEEPALIVE;
//UART0_SendByte(0x91);
//client_err = 2;//初始化成功
if(client_err == 2)
{
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
{
//UART0_SendByte(0x92);
client_err = 0;//未初始化成功
//UART0_SendStr("state4\r\n");
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);
}
}
/**
* @brief Function called when TCP connection established
* @param tpcb: pointer on the connection contol block
* @param err: when connection correctly established err should be ERR_OK
* @retval err_t: returned error
*/
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";
//UART0_SendByte(0xA0);
if (err == ERR_OK)
{
client_err = 2;//初始化成功进入回调函数
//UART0_SendByte(0xA1);
/* allocate structure es to maintain tcp connection informations */
es = (struct client *)mem_malloc(sizeof(struct client));
if (es != NULL)
{
es->state = ES_CONNECTED;
es->pcb = tpcb;
//sprintf((char*)data, "sending tcp client message %d", message_count);
//UART0_SendByte(0x11);
/* allocate pbuf */
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_sent(tpcb, tcp_client_sent);
tcp_poll(tpcb, tcp_client_poll, 1);
//tcp_client_send(tpcb,es);
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);
//UART0_SendByte(0x22);
return ERR_OK;
}
}
else
{
/* close connection */
tcp_client_connection_close(tpcb, es);
client_err=1;
UART0_SendByte(0xa2);
/* return memory allocation error */
return ERR_MEM;
}
}
else
{
/* close connection */
tcp_client_connection_close(tpcb, es);
client_err=1;
UART0_SendByte(0xa3);
}
UART0_SendByte(0xa4);
return err;
}
/**
* @brief tcp_receiv callback
* @param arg: argument to be passed to receive callback
* @param tpcb: tcp connection control block
* @param err: receive error code
* @retval err_t: retuned error
*/
static err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
struct client *es;
err_t ret_err;
LWIP_ASSERT("arg != NULL",arg != NULL);
es = (struct client *)arg;
/* if we receive an empty tcp frame from server => close connection */
if (p == NULL)
{
/* remote host closed connection */
es->state = ES_CLOSING;
if(es->p_tx == NULL)
{
// we're done sending, close connection
tcp_client_connection_close(tpcb, es);
//UART0_SendByte(0xa3);
client_err=1;
UART0_SendString("tcp_client__close\r\n",sizeof("tcp_client_connection_close\r\n"));
}
/*else
{
// send remaining data
tcp_sent(tpcb, tcp_client_sent);
tcp_client_send(tpcb, es);
UART0_SendByte(0x33);
}*/
ret_err = ERR_OK;
}
/* else : a non empty frame was received from echo server but for some reason err != ERR_OK */
else if(err != ERR_OK)
{
/* free received pbuf*/
if (p != NULL)
{
pbuf_free(p);
}
ret_err = err;
}
else if(es->state == ES_CONNECTED)
{
//tcp_sent(tpcb, tcp_client_sent);
//tcp_client_send(tpcb, es);
//client_pcb = tpcb;
//if(tcp_sndbuf(tpcb) > p->tot_len)
//tcp_write(tpcb, p->payload, p->tot_len, TCP_WRITE_FLAG_COPY);
/* Acknowledge data reception */
tcp_recved(tpcb, p->tot_len);
tcp_recv_flag = 1;
//UART0_SendString(can1_buf,can1_len);
//CAN1_Send_Data(CAN1_SEND_ID,can1_buf,can1_len); // payload为TCP数据块的起始位置
pbuf_free(p);
ret_err = ERR_OK;
}
/* data received when connection already closed */
else
{
/* Acknowledge data reception */
tcp_recved(tpcb, p->tot_len);
/* free pbuf and do nothing */
pbuf_free(p);
ret_err = ERR_OK;
}
return ret_err;
}
/**
* @brief function used to send data
* @param tpcb: tcp control block
* @param es: pointer on structure of type client containing info on data
* to be sent
* @retval None
*/
static void tcp_client_send(struct tcp_pcb *tpcb, struct client * es)
{
struct pbuf *ptr;
err_t wr_err = ERR_OK;
while ((wr_err == ERR_OK) &&
(es->p_tx != NULL) &&
(es->p_tx->len <= tcp_sndbuf(tpcb)))
{
/* get pointer on pbuf from es structure */
ptr = es->p_tx;
/* enqueue data for transmission */
wr_err = tcp_write(tpcb, ptr->payload, ptr->len, 1);
if (wr_err == ERR_OK)
{
/* continue with next pbuf in chain (if any) */
es->p_tx = ptr->next;
if(es->p_tx != NULL)
{
/* increment reference count for es->p */
pbuf_ref(es->p_tx);
}
/* free pbuf: will free pbufs up to es->p (because es->p has a reference count > 0) */
pbuf_free(ptr);
}
else if(wr_err == ERR_MEM)
{
/* we are low on memory, try later, defer to poll */
es->p_tx = ptr;
}
else
{
/* other problem ?? */
}
}
}
/**
* @brief This function implements the tcp_poll callback function
* @param arg: pointer on argument passed to callback
* @param tpcb: tcp connection control block
* @retval err_t: error code
*/
static err_t tcp_client_poll(void *arg, struct tcp_pcb *tpcb)
{
err_t ret_err;
struct client *es;
es = (struct client*)arg;
if (es != NULL)
{
if (es->p_tx != NULL)
{
/* there is a remaining pbuf (chain) , try to send data */
tcp_client_send(tpcb, es);
}
else
{
/* no remaining pbuf (chain) */
if(es->state == ES_CLOSING)
{
/* close tcp connection */
tcp_client_connection_close(tpcb, es);
client_err=1;
//UART0_SendByte(0xa4);
}
}
ret_err = ERR_OK;
}
else
{
/* nothing to be done */
tcp_abort(tpcb);
ret_err = ERR_ABRT;
}
return ret_err;
}
/**
* @brief This function implements the tcp_sent LwIP callback (called when ACK
* is received from remote host for sent data)
* @param arg: pointer on argument passed to callback
* @param tcp_pcb: tcp connection control block
* @param len: length of data sent
* @retval err_t: returned error code
*/
static err_t tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
struct client *es;
LWIP_UNUSED_ARG(len);
es = (struct client *)arg;
if(es->p_tx != NULL)
{
tcp_client_send(tpcb, es);
}
return ERR_OK;
}
/**
* @brief This function is used to close the tcp connection with server
* @param tpcb: tcp connection control block
* @param es: pointer on client structure
* @retval None
*/
static void tcp_client_connection_close(struct tcp_pcb *tpcb, struct client * es )
{
/* remove callbacks */
tcp_recv(tpcb, NULL);
tcp_sent(tpcb, NULL);
tcp_poll(tpcb, NULL,0);
if (es != NULL)
{
mem_free(es);
}
/* close tcp connection */
tcp_close(tpcb);
}
#endif /* LWIP_TCP */
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ |
|