2015年12月9日 BY : TATERLI
TCP比UDP就复杂多了,UDP就像串口一样发发随便奶奶,但是TCP不是,有监听啊,查询啊什么,可以看看电脑的TCP连接,多得呢.
所以,在官方的例子你们,TCP Client就是6个函数:
static err_t tcp_echoclient_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err);
static void tcp_echoclient_connection_close(struct tcp_pcb *tpcb, struct echoclient * es);
static err_t tcp_echoclient_poll(void *arg, struct tcp_pcb *tpcb);
static err_t tcp_echoclient_sent(void *arg, struct tcp_pcb *tpcb, u16_t len);
static void tcp_echoclient_send(struct tcp_pcb *tpcb, struct echoclient * es);
static err_t tcp_echoclient_connected(void *arg, struct tcp_pcb *tpcb, err_t err);
而TCP Server则有7个那么多.
static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err);
static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err);
static void tcp_echoserver_error(void *arg, err_t err);
static err_t tcp_echoserver_poll(void *arg, struct tcp_pcb *tpcb);
static err_t tcp_echoserver_sent(void *arg, struct tcp_pcb *tpcb, u16_t len);
static void tcp_echoserver_send(struct tcp_pcb *tpcb, struct tcp_echoserver_struct *es);
static void tcp_echoserver_connection_close(struct tcp_pcb *tpcb, struct tcp_echoserver_struct *es);
形象地说,TCP模拟成一个教室的通信,而TCP Server时候,你就是老师,而TCP Client时候,你就是学生,老师可以接受很多学生提问,也可以给单独一个学生说话,也可以群体发话,学生之间不能之间聊天,只能跟老师说话.TCP Server和TCP Client可以共存在一个板子上,他们端口肯定是不一样的.如果是TCP Server,老师,只要知道课室是哪个,就能找到学生,而学生要找老师,就得跟着老师去了哪个课室,这样,是不是挺好理解的.
我们用官方的例子,但是进行一些分析.首先是创建一个老师啊.
void tcp_echoserver_init(void)
{
tcp_echoserver_pcb = tcp_new();
if (tcp_echoserver_pcb != NULL)
{
err_t err;
err = tcp_bind(tcp_echoserver_pcb, IP_ADDR_ANY, 7); /* TCP绑定 */
if (err == ERR_OK)
{
tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb); /* 开始监听(等学生来) */
tcp_accept(tcp_echoserver_pcb, tcp_echoserver_accept); /* 如果有什么动静,需要通知我,这个函数. */
}
}
}
然后再生成回调:
static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
if (es != NULL)
{
/* 当收到数据时 */
tcp_recv(newpcb, tcp_echoserver_recv);
/* 当出错时 */
tcp_err(newpcb, tcp_echoserver_error);
/* 当轮询时 */
tcp_poll(newpcb, tcp_echoserver_poll, 1);
ret_err = ERR_OK;
}
}
对于收到数据的处理方法:
static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
/* 空TCP数据 */
if (p == NULL)
{
ret_err = ERR_OK;
}
/* 非空但是数据不正确 */
else if(err != ERR_OK)
{
ret_err = err;
}
/* 连接成功 */
else if(es->state == ES_ACCEPTED)
{
ret_err = ERR_OK;
}
/* 收到数据 */
else if (es->state == ES_RECEIVED)
{
ret_err = ERR_OK;
}
/* 连接关闭后还能收到数据 */
else
{
ret_err = ERR_OK;
}
return ret_err;
}
然后这个其实只需要tcp_echoserver_init,后续就一切可以了.一直监听,如果有数据,就会进入处理流程.
如果我们作为Client,就不断的发送新数据给老师(服务器).所以要知道老师的地址.所以,连接时候不一样,其他逻辑基本一样.
void tcp_echoclient_connect(void){ struct ip_addr DestIPaddr; /* create new tcp pcb */ echoclient_pcb = tcp_new(); if (echoclient_pcb != NULL) { IP4_ADDR( &DestIPaddr, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3 ); /* connect to destination address/port */ tcp_connect(echoclient_pcb,&DestIPaddr,DEST_PORT,tcp_echoclient_connected); } else { /* deallocate the pcb */ memp_free(MEMP_TCP_PCB, echoclient_pcb);#ifdef SERIAL_DEBUG printf("\r can not create tcp pcb");#endif }}
其他都是一样的,那么,对于TCP的高级应用,TCP Web,就没什么难度了,就不多说了.例程:
本文主要介绍了TCP和UDP的差异,指出TCP更为复杂。以教室通信形象类比TCP Server和TCP Client的关系,还对官方TCP示例进行分析,阐述创建TCP Server、生成回调及数据处理方法,说明作为Client时的操作逻辑,最后提及TCP Web应用。

3576

被折叠的 条评论
为什么被折叠?



