标签:
既然udp说完了,那接下来自然就是TCP通讯了,今天说说TCP客户端通讯,也就是单片机作为客户端,主机PC作为服务器
相比于udp而言,tcp增加了一个连接服务器的流程,首先还是创建tcp_client任务
//创建TCP客户端线程 //返回值:0 TCP客户端创建成功 // 其他 TCP客户端创建失败 INT8U tcp_client_init(void) { INT8U res; OS_CPU_SR cpu_sr; OS_ENTER_CRITICAL(); //关中断 res = OSTaskCreate(tcp_client_thread,(void*)0,(OS_STK*)&TCPCLIENT_TASK_STK[TCPCLIENT_STK_SIZE-1],TCPCLIENT_PRIO); //创建TCP客户端线程 OS_EXIT_CRITICAL(); //开中断 return res; }
任务的执行流程如下
//tcp客户端任务函数 static void tcp_client_thread(void *arg) { OS_CPU_SR cpu_sr; u32 data_len = 0; struct pbuf *q; err_t err,recv_err; static ip_addr_t server_ipaddr,loca_ipaddr; static u16_t server_port,loca_port; LWIP_UNUSED_ARG(arg); server_port = REMOTE_PORT; IP4_ADDR(&server_ipaddr, 192,168, 1,105); while(dhcpstatus != 2)//等待dhcp成功 { OSTimeDly(10); //printf("wait dhcp\r\n"); } while (1) { tcp_clientconn = netconn_new(NETCONN_TCP); //创建一个TCP链接 err = netconn_connect(tcp_clientconn,&server_ipaddr,server_port);//连接服务器 if(err != ERR_OK) netconn_delete(tcp_clientconn); //返回值不等于ERR_OK,删除tcp_clientconn连接 else if (err == ERR_OK) //处理新连接的数据 { struct netbuf *recvbuf; tcp_clientconn->recv_timeout = 10; netconn_getaddr(tcp_clientconn,&loca_ipaddr,&loca_port,1); //获取本地IP主机IP地址和端口号 printf("连接上服务器%d.%d.%d.%d,本机端口号为:%d\r\n",192,168, 1,105,loca_port); while(1) { if(keyValue == KEY_LEFT) { tcp_client_flag = LWIP_SEND_DATA; keyValue = 0; } if((tcp_client_flag & LWIP_SEND_DATA) == LWIP_SEND_DATA) //有数据要发送 { err = netconn_write(tcp_clientconn ,tcp_client_sendbuf,strlen((char*)tcp_client_sendbuf),NETCONN_COPY); //发送tcp_server_sentbuf中的数据 if(err != ERR_OK) { printf("发送失败\r\n"); } tcp_client_flag &= ~LWIP_SEND_DATA; } if((recv_err = netconn_recv(tcp_clientconn,&recvbuf)) == ERR_OK) //接收到数据 { OS_ENTER_CRITICAL(); //关中断 memset(tcp_client_recvbuf,0,TCP_CLIENT_RX_BUFSIZE); //数据接收缓冲区清零 for(q=recvbuf->p;q!=NULL;q=q->next) //遍历完整个pbuf链表 { //判断要拷贝到TCP_CLIENT_RX_BUFSIZE中的数据是否大于TCP_CLIENT_RX_BUFSIZE的剩余空间,如果大于 //的话就只拷贝TCP_CLIENT_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据 if(q->len > (TCP_CLIENT_RX_BUFSIZE-data_len)) memcpy(tcp_client_recvbuf+data_len,q->payload,(TCP_CLIENT_RX_BUFSIZE-data_len));//拷贝数据 else memcpy(tcp_client_recvbuf+data_len,q->payload,q->len); data_len += q->len; if(data_len > TCP_CLIENT_RX_BUFSIZE) break; //超出TCP客户端接收数组,跳出 } OS_EXIT_CRITICAL(); //开中断 data_len=0; //复制完成后data_len要清零。 printf("%s\r\n",tcp_client_recvbuf); netbuf_delete(recvbuf); }else if(recv_err == ERR_CLSD) //关闭连接 { netconn_close(tcp_clientconn); netconn_delete(tcp_clientconn); printf("服务器%d.%d.%d.%d断开连接\r\n",192,168, 1,105); break; } } } OSTimeDly(10); } }
里面核心的就是netconn的使用,这个熟能生巧
忘了传代码,补上
http://download.csdn.net/detail/dengrengong/8599071
LWIP_STM32_ENC28J60_NETCONN_TCP_CLIENT(4)
标签:
原文地址:http://www.cnblogs.com/dengxiaojun/p/4433729.html