#include "tcp_server_demo.h" #include "lwip/opt.h" #include "lwip_comm.h" #include "led.h" #include "lwip/lwip_sys.h" #include "lwip/api.h" #include "usr_infor.h" #include "base64.h" #include "malloc.h" #include "protohandle.h" #include "sram.h" #include "main.h" DataPack pack; #if _USE_MBOX//邮箱 extern OS_EVENT *mbox; #endif #if _USE_QUE extern OS_EVENT *que; #endif //tcp服务器任务 void tcp_server_thread(void *arg) { OS_CPU_SR cpu_sr; u8 tcp_server_recv[TCP_SERVER_RX_BUFSIZE]; //TCP客户端接收数据缓冲区 u32 data_len = 0; struct pbuf *q; err_t err,recv_err; u8 remot_addr[4]; struct netconn *conn, *newconn; static ip_addr_t ipaddr; static u16_t peer_local; u16_t local_serv_port = 8088;// default char *pb = NULL; size_t n; INT8U error; LWIP_UNUSED_ARG(arg); local_serv_port = getLocalPort(LOCAL_ETC_ADDR);//读取Flash 设备配置 printf("local server port = %d\r\n",local_serv_port); conn = netconn_new(NETCONN_TCP); //创建一个TCP链接 netconn_bind(conn,IP_ADDR_ANY,local_serv_port); //绑定端口8088号端口 netconn_listen(conn); //进入监听模式 conn->recv_timeout = 10; //禁止阻塞线程 等待10ms printf("开始服务器线程\r\n"); while (1) { err = netconn_accept(conn,&newconn); //接收连接请求 newconn->recv_timeout = 10; memset(tcp_server_recv,0,TCP_SERVER_RX_BUFSIZE); if (err == ERR_OK) //处理新连接的数据 { struct netbuf *recvbuf; // 传出参数 netconn_getaddr(newconn,&ipaddr,&peer_local,0); //获取远端IP地址和端口号 remot_addr[3] = (uint8_t)(ipaddr.addr >> 24); // 客户端的IP地址 remot_addr[2] = (uint8_t)(ipaddr.addr>> 16); remot_addr[1] = (uint8_t)(ipaddr.addr >> 8); remot_addr[0] = (uint8_t)(ipaddr.addr); printf("主机%d.%d.%d.%d连接上服务器,主机端口号为:%d\r\n",remot_addr[0], remot_addr[1],remot_addr[2],remot_addr[3],peer_local); while(1) { if((recv_err = netconn_recv(newconn,&recvbuf)) == ERR_OK) //接收到数据 { OS_ENTER_CRITICAL(); //关中断 memset(tcp_server_recv,0,TCP_SERVER_RX_BUFSIZE); //数据接收缓冲区清零 for(q=recvbuf->p; q!=NULL; q=q->next) //遍历完整个pbuf链表 { //判断要拷贝到TCP_SERVER_RX_BUFSIZE中的数据是否大于TCP_SERVER_RX_BUFSIZE的剩余空间,如果大于 //的话就只拷贝TCP_SERVER_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据 if(q->len > (TCP_SERVER_RX_BUFSIZE-data_len)) memcpy(tcp_server_recv+data_len,q->payload,(TCP_SERVER_RX_BUFSIZE-data_len));//拷贝数据 else memcpy(tcp_server_recv+data_len,q->payload,q->len); data_len += q->len; if(data_len > TCP_SERVER_RX_BUFSIZE) break; //超出TCP客户端接收数组,跳出 } data_len=0; //复制完成后data_len要清零 OS_EXIT_CRITICAL(); //开中断 // base64 decoder // check // unpacket //respose 可能需要另外一个任务 printf("before decoder:%s\r\n",tcp_server_recv); //通过串口发送接收到的数据 printf("strlen((char *)tcp_server_recv) = %d\r\n",strlen((char *)tcp_server_recv)); pb = decode_base64((const char*)tcp_server_recv,&n); if(pb != NULL) { printf("After decoder:%s\r\n",pb); printf("strlen(pb) = %d\r\n",n); if(pb[0] !='<' || pb[1] !='c' || pb[2] !='m' || pb[3] !='d' || pb[4] !='>') { printf("recv a unknow stream\r\n"); } else { printf("Begin Process\r\n"); OS_ENTER_CRITICAL(); //关中断 UnPackData1(pb,&pack); OS_EXIT_CRITICAL(); //开中断 #if _USE_MBOX error = OSMboxPostOpt(mbox,(void *)&pack,OS_POST_OPT_BROADCAST); //error = OSMboxPostOpt(mbox,&pack,OS_POST_OPT_NONE); if(error == OS_ERR_NONE) printf("Send MBox success\r\n"); else if(error == OS_ERR_MBOX_FULL) printf("MBox is full\r\n"); else if(error == OS_ERR_PEVENT_NULL) printf("Mbox mbox == NULL\r\n"); else if(error == OS_ERR_POST_NULL_PTR) printf("Mbox msg == NULL\r\n"); // 挂起任务 //OSTaskSuspend(DECODE_USART_TASK_PRO); //OSTaskSuspend(MAN_IDENTIFY_TASK_PRIO); //OSTaskSuspend(UDISK_TASK_PRIO); //OSTaskSuspend(GET_TIME_TASK_PRO); #endif #if _USE_QUE error = OSQPost(que,(void *)&pack); if(error == OS_ERR_PEVENT_NULL) printf("OS_ERR_PEVENT_NULL\r\n"); else if(error == OS_ERR_EVENT_TYPE) printf("OS_ERR_EVENT_TYPE\r\n"); else if(error == OS_ERR_Q_FULL) printf("OS_ERR_Q_FULL\r\n"); #endif OS_ENTER_CRITICAL(); //关中断 printf("unpack ok\r\n"); printf("datapack.type=%d\r\n",pack.type); OS_EXIT_CRITICAL(); //开中断 //OSTimeDlyHMSM(0,0,0,100); #if !(_USE_QUE && USE_MBOX) ProtolResponse1(&pack); #endif } myfree(SRAMIN,pb); break; } else { printf("failed : Decoder heap\r\n"); break; } netbuf_delete(recvbuf); } else if(recv_err == ERR_CLSD) //关闭连接 { netconn_close(newconn); netconn_delete(newconn); printf("主机:%d.%d.%d.%d断开与服务器的连接\r\n",remot_addr[0], remot_addr[1],remot_addr[2],remot_addr[3]); break; } } OSTimeDlyHMSM(0,0,0,100); } } // end while(1) } /**************************************** 问题描述: 用TCP客户端 连接 板子 服务器 如果客户端不给SERV发送数据,客户端 连接 断开 正常 如果客户端给SEVR发送数据,客户端 连接 断开 服务器 几次之后,板子程序死机。 根据串口打印信息,只能看到 客户端 连接 服务器 ,看不到 客户端 断开 服务器 ******************************************/ /*************************************************************************************************************** if(tcp_server_recv[0] != '<' || tcp_server_recv[1] != 'c' || tcp_server_recv[2] != 'm' || tcp_server_recv[3] != 'd' || tcp_server_recv[4] != '>') { printf("RECV a unKown String\r\n"); } else { printf("Begin Process\r\n"); UnPackData1((char *)tcp_server_recv,&pack); printf("unpack ok\r\n"); printf("datapack.type=%d\r\n",pack.type); //ProtolResponse1(&pack); } **************************************************************************************************************/