完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
现在我正使用lwip的非阻塞socket作为tcp通信手段,然后在此过程中,进行https的ota操作,然后发现出现socket read fail问题 并且https也无法使用,若将当前socket关闭,则可以正常进行https升级,请问下有什么好的方法能解决此问题?(当前是wifi sta模式)
另外发现若采用以太网模式(不使用wifi,则https可以正常OTA,但是tcp还是会提示失败) 使用wifi log如下(tcp read 返回-9错误): [0;32mI (46199) HXJ_OTA: Starting OTA example...[0m [0;32mI (46199) HXJ_OTA: config.URL:https://file.hxjiot.com/firmware/C849A7 ... 18A870.bin[0m [0;32mI (46209) HXJ_OTA: Running partition type 0 subtype 16 (offset 0x00080000)[0m [0;32mI (46229) HXJ_TCPCLIENT: tcp错误errono=9[0m [0;32mI (46229) HXJ_TCPCLIENT: tcp read failed [0m [0;31mE (46239) esp-tls: mbedtls_ssl_setup returned -0x7f00 [0m [0;31mE (46249) esp-tls: Failed to open new connection[0m [0;31mE (46249) TRANS_SSL: Failed to open a new connection[0m [0;31mE (46249) HTTP_CLIENT: Connection failed, sock < 0[0m [0;32mI (46259) HXJ_OTA: HTTP_EVENT_DISCONNECTED[0m [0;31mE (46259) HXJ_OTA: Failed to open HTTP connection: ESP_ERR_HTTP_CONNECT[0m [0;31mE (46269) HXJ_OTA: Firmware Upgrades Failed[0m [/code] 使用以太网 log如下 (一开始进行https,则tcp read马上返回 -9错误) Code: Select all [0;32mI (17869) HXJ_OTA: Starting OTA example...[0m[0;32mI (17869) HXJ_OTA: config.URL:https://file.hxjiot.com/firmware/C849A7A10470000151FB14E91918A870.bin[0m[0;32mI (17879) HXJ_OTA: Running partition type 0 subtype 16 (offset 0x00080000)[0m[0;32mI (17899) HXJ_TCPCLIENT: tcp错误errono=9[0m[0;32mI (17899) HXJ_TCPCLIENT: tcp read failed[0m[0;32mI (18969) HXJ_OTA: HTTP_EVENT_ON_CONNECTED[0m[0;32mI (18989) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Server, value=Tengine[0m[0;32mI (18989) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Content-Type, value=application/octet-stream[0m[0;32mI (18989) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Content-Length, value=1015536[0m[0;32mI (18999) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Connection, value=keep-alive[0m[0;32mI (19009) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Date, value=Fri, 11 Jan 2019 04:21:14 GMT[0m[0;32mI (19009) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Accept-Ranges, value=bytes[0m[0;32mI (19019) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Access-Control-Allow-Origin, value=*[0m[0;32mI (19029) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Access-Control-Expose-Headers, value=X-Log, X-Reqid[0m[0;32mI (19039) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Access-Control-Max-Age, value=2592000[0m[0;32mI (19049) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Cache-Control, value=public, max-age=31536000[0m[0;32mI (19059) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Content-Disposition, value=inline; filename="C849A7A10470000151FB14E91918A870.bin"; filename*=utf-8' 'C849A7A10470000151FB14E91918A870.bin[0m[0;32mI (19069) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Content-Transfer-Encoding, value=binary[0m[0;32mI (19079) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Etag, value="F[0m[0;32mI (19089) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Last-Modified, value=Wed, 09 Jan 2019 08:47:51 GMT[0m[0;32mI (19099) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=X-Log, value=redis.g/404;mc.g/404;redis.g;rs40_shard.sel:5;rwro.get:5;RS.dbs:5;RS:5;redis.s;1s.gh:27;PFDS:28;IO:37[0m[0;32mI (19109) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=X-M-Log, value=QNM:xs459;SRCPROXY:xs485;SRC:37;SRCPROXY:37;QNM3:40[0m[0;32mI (19119) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=X-M-Reqid, value=PSoAAFphsNFxsHgV[0m[0;32mI (19129) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=X-Qiniu-Zone, value=0[0m[0;32mI (19139) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=X-Qnm-Cache, value=Miss[0m[0;32mI (19149) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=X-Reqid, value=rVIAAMnh3tFxsHgV[0m[0;32mI (19149) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=X-Svr, value=IO[0m[0;32mI (19159) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Ali-Swift-Global-Savetime, value=1547180474[0m[0;32mI (19169) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Via, value=cache35.l2su18-2[184,200-0,M], cache36.l2su18-2[186,0], vcache5.cn627[0,200-0,H], vcache7.cn627[1,0][0m[0;32mI (19179) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Age, value=10843[0m[0;32mI (19189) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=ache, value=HIT TCP_MEM_HIT dirn:12:155996968[0m[0;32mI (19199) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=X-Swift-SaveTime, value=Fri, 11 Jan 2019 04:21:15 GMT[0m[0;32mI (19209) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=X-Swift-CacheTime, value=2592000[0m[0;32mI (19219) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=Timing-Allow-Origin, value=*[0m[0;32mI (19219) HXJ_OTA: HTTP_EVENT_ON_HEADER, key=EagleId, value=7909f64715471913177701228e[0m[0;32mI (19229) HXJ_OTA: HTTP_EVENT_ON_DATA, len=195[0m[0;32mI (19239) HXJ_OTA: Starting OTA...[0m[0;32mI (19239) HXJ_OTA: Writing to partition subtype 17 at offset 0x240000[0m[0;32mI (20699) HXJ_OTA: esp_ota_begin succeeded[0m[0;32mI (20699) HXJ_OTA: Please Wait. This may take time[0m[0;32mI (20709) HXJ_OTA: HTTP_EVENT_ON_DATA, len=317[0m[0;32mI (20709) HXJ_OTA: Written image length 512[0m[0;32mI (20709) HXJ_OTA: HTTP_EVENT_ON_DATA, len=512[0m[0;32mI (20719) HXJ_OTA: Written image length 1024[0m[0;32mI (20719) HXJ_OTA: HTTP_EVENT_ON_DATA, len=512[0m[0;32mI (20729) HXJ_OTA: Written image length 1536[0m[0;32mI (20729) HXJ_OTA: HTTP_EVENT_ON_DATA, len=59[0m[0;32mI (20739) HXJ_OTA: HTTP_EVENT_ON_DATA, len=453[0m 非阻塞tcp实现代码如下:Code: Select all /*============================================================================== * Function: new_tcp_read() * Description: 非阻塞tcp读取 * Input: none * Return: none * Others: none *============================================================================*/static int new_tcp_read(int tcp_fd, unsigned char* buf, unsigned short len){ int ret = -1; if(buf == NULL) { return -1; } /*TCP读取数据需要判断错误码*/ ret = (int)(recv(tcp_fd, buf, len, MSG_DONTWAIT)); if(ret <= 0) { if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { return 0;//OK } else { ESP_LOGI(TAG,"tcp错误errono=%d",errno); return -1; } } return ret;}/*============================================================================== * Function: new_tcp_state() * Description: 非阻塞tcp设置参数 * Input: none * Return: none * Others: none *============================================================================*/static int new_tcp_state(int sock){ int errcode = 0; int tcp_fd = sock; if(tcp_fd < 0) { return -1; } #if 1 fd_set rset, wset; int ready_n; FD_ZERO(&rset); FD_SET(tcp_fd, &rset); wset = rset; struct timeval timeout; timeout.tv_sec = 3; timeout.tv_usec = 0; /*使用select机制判断tcp连接状态*/ ready_n = select(tcp_fd + 1, &rset, &wset, NULL, &timeout); if(0 == ready_n) { ESP_LOGI(TAG,"select time outn"); errcode = -1; } else if(ready_n < 0) { ESP_LOGI(TAG,"select errorn"); errcode = -1; } else { // ESP_LOGI(TAG,"FD_ISSET(tcp_fd, &rset):%dn FD_ISSET(tcp_fd, &wset):%dn",// (int)FD_ISSET(tcp_fd, &rset) , (int)FD_ISSET(tcp_fd, &wset)); // test in linux environment,kernel version 3.5.0-23-generic // tcp server do not send msg to client after tcp connecting int ret; socklen_t len = sizeof(int); if(0 != getsockopt (tcp_fd, SOL_SOCKET, SO_ERROR, &ret, (socklen_t*)&len)) { ESP_LOGI(TAG,"getsocketopt failedrn"); errcode = -1; } // ESP_LOGI(TAG,"getsocketopt ret=%d errno %drn",ret, errno); if(0 != ret) { ESP_LOGI(TAG,"getsocketopt ret=%d errno %drn",ret, errno); errcode = -1; } }#endif int ret; socklen_t len = sizeof(int); if(0 != getsockopt (tcp_fd, SOL_SOCKET, SO_ERROR, &ret, (socklen_t*)&len)) { ESP_LOGI(TAG,"getsocketopt failedrn"); errcode = -1; } // ESP_LOGI(TAG,"getsocketopt ret=%d errno %drn",ret, errno); if(0 != ret) { ESP_LOGI(TAG,"getsocketopt ret=%d errno %drn",ret, errno); errcode = -1; } return errcode;}/*============================================================================== * Function: new_tcp_send() * Description: 非阻塞tcp发送 * Input: none * Return: none * Others: none *============================================================================*/int new_tcp_send(int tcp_fd, const unsigned char* buf, unsigned short len){ int ret = -1; if(buf == NULL) { return -1; } /*TCP发送数据需要判断错误码*/ ret = (int)(send(tcp_fd, buf, len, MSG_DONTWAIT)); if(ret < 0) { if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { return 0; } else { return -1; } } ESP_LOGI(TAG,"new_tcp_send=%d",ret); return ret;}static int new_tcp_connect(in_addr_t srcip,const char* dst, unsigned short port){ struct sockaddr_in servaddr; int tcp_fd; int flags; int reuse; if(NULL == dst) { return -1; } tcp_fd = socket(AF_INET, SOCK_STREAM, 0); if(tcp_fd < 0) { ESP_LOGI(TAG,"creat socket tcp_fd failedn"); return -1; } /*设置非阻塞模式*/ flags = fcntl(tcp_fd, F_GETFL, 0); if(flags < 0 || fcntl(tcp_fd, F_SETFL, flags | O_NONBLOCK) < 0) { ESP_LOGI(TAG,"fcntl: %sn", strerror(errno)); close(tcp_fd); return -1; } reuse = 1; if(setsockopt(tcp_fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &reuse, sizeof( reuse ) ) != 0 ) { close(tcp_fd); ESP_LOGI(TAG,"set SO_REUSEADDR failedn"); return -1; } memset(&servaddr, 0, sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr(dst); servaddr.sin_port = htons(port); struct sockaddr_in src; memset(&src,0,sizeof(struct sockaddr_in)); src.sin_addr.s_addr = srcip;//使用sta的 ip src.sin_family = AF_INET; src.sin_port=htons(10000); //destAddr.sin_port = htons(PORT); //绑定一下 ip //bind(tcp_fd,&src,sizeof(struct sockaddr)); if(connect(tcp_fd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in)) == 0) { return tcp_fd; } else { if(errno == EINPROGRESS) { ESP_LOGI(TAG,"tcp conncet noblockn"); return tcp_fd; } else { close(tcp_fd); return -1; } }} 整体逻辑如下:Code: Select all tcp_fd = new_tcp_connect( (in_addr_t)sta_ip.ip.addr,Host, Port);//recv_len为1024if(new_tcp_state(tcp_fd)!= 0){ ESP_LOGI(TAG,"tcp not connectn"); break; // continue;}else{ ESP_LOGI(TAG,"tcp connect successufllyn"); tcp_connect_flag = 1;}while(1){ //省略发送等其他逻辑 recv_len = new_tcp_read(tcp_fd, tcp_reveive_buffer, tcp_max_size-1); if(recv_len > 0) { ESP_LOGI(TAG,"recv data:%s,length:%dn", tcp_reveive_buffer, recv_len); InterNet_Receive((char *)&tcp_reveive_buffer,recv_len); clilenttcp_get_answer=1; } else if(recv_len == 0) { // ESP_LOGI(TAG,"recv no datan"); // continue; } else { ESP_LOGI(TAG,"tcp read failedn"); break; } vTaskDelay(30 / portTICK_PERIOD_MS);//每30ms读取1K数据}//TCP失败到此 请问下有没有方法能同时运行tcp socket和https服务?? |
|
相关推荐
1个回答
|
|
在LwIP中,非阻塞TCP socket和HTTPS服务可以同时运行,但需要确保正确地管理它们之间的资源和调度。从您提供的信息来看,您在WiFi STA模式下遇到了socket read失败的问题,而在以太网模式下HTTPS OTA可以正常工作。以下是一些建议来解决这个问题:
1. **确保线程调度**:在多任务环境中,确保LwIP的任务调度器(例如`tcpip_thread`)能够正确运行。这通常意味着您需要在应用程序中创建一个单独的线程来处理LwIP的任务。 2. **检查内存分配**:确保您的系统有足够的堆内存来处理TCP连接和HTTPS请求。如果内存不足,可能导致socket操作失败。 3. **优化超时设置**:检查您的LwIP配置中的超时设置,确保它们适合您的网络环境。过短的超时可能导致socket操作失败。 4. **错误处理**:在您的代码中添加更详细的错误处理和日志记录,以便更好地了解问题所在。例如,当socket read失败时,记录错误代码和相关上下文信息。 5. **避免阻塞操作**:确保在处理TCP socket和HTTPS请求时,不要使用阻塞操作。这可能导致任务调度器无法正常工作,从而影响整个系统的稳定性。 6. **调整优先级**:如果可能的话,尝试调整LwIP任务和HTTPS任务的优先级,以确保它们能够合理地共享CPU资源。 7. **考虑使用其他库**:如果您发现LwIP在非阻塞模式下的性能不佳,可以考虑使用其他支持非阻塞操作的网络库,例如mbedTLS(用于HTTPS)和lwIP的替代品。 8. **更新固件和库**:确保您的设备固件和使用的库(如LwIP和mbedTLS)是最新版本,以获得最佳的性能和稳定性。 通过以上建议,您应该能够找到并解决在WiFi STA模式下遇到的socket read失败问题。同时,确保在以太网模式下也进行相应的优化,以提高整个系统的稳定性和性能。 |
|
|
|
只有小组成员才能发言,加入小组>>
140 浏览 0 评论
1158 浏览 1 评论
584浏览 6评论
482浏览 5评论
有没有办法在不使用混杂模式的情况下实现Wifi驱动程序接收缓冲区访问中断呢?
467浏览 5评论
466浏览 4评论
441浏览 4评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 19:42 , Processed in 0.882800 second(s), Total 82, Slave 65 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号