开发板:esp-32
问题描述:
重复连接WiFi时,会无法创建socket,因此,我使用 SO_LINGER 参数,希望tcp断开时立马释放socket;同时,我希望发送tcp的等待超时时间为5秒,为此使用 SO_SNDTIMEO 参数,这里我遇到了两个问题:
问题1:
SO_SNDTIMEO 似乎未正常生效,我设置connect超时时间为5秒,超过五秒connect并没有结束,是我使用方法出现问题了吗?
menuconfig已做如下设置:LWIP_SO_LINGER(=y) "Enable SO_LINGER processing"
问题2:
在反复开关wifi后,产生如下log的错误:
Code: Select all
#######################################rxBytes:14, buffer data:126 0 11 18 8 49 50 51 52 53 54 55 56 18
I (1710426) wifi:state: run -> init (0)
I (1710426) wifi:pm stop, total sleep time: 4238202 us / 4972342 us
I (1710426) wifi:new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
saveWifiConfigInNvs(91) Updating wifi config in NVS ...
I (1710476) wifi:new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (1710486) wifi:state: init -> auth (b0)
I (1710486) wifi:state: auth -> assoc (0)
I (1710486) wifi:state: assoc -> run (10)
I (1710506) wifi:connected with 111111, aid = 1, channel 6, BW20, bssid = 94:a6:7e:41:be:c1
I (1710506) wifi:security: WPA2-PSK, phy: bg, rssi: -51
I (1710506) wifi:pm start, type: 1
I (1710516) esp_netif_handlers: sta ip: 192.168.142.18, mask: 255.255.255.0, gw: 192.168.142.254
wifiEventHandler(211) got ip:192.168.142.18
I (1710526) esp_netif_handlers: sta ip: 192.168.142.18, mask: 255.255.255.0, gw: 192.168.142.254
wifiEventHandler(211) got ip:192.168.142.18
I (1710546) wifi:AP's beacon interval = 102400 us, DTIM period = 2
#######################################rxBytes:30, buffer data:126 0 27 65 13 49 57 50 46 49 54 56 46 49 52 50 46 51 0 9 1 2 3 4 5 6 7 8 9 107
I (1715436) TCP client: Socket created, connecting to 192.168.142.3:3333
Guru Meditation Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x40013fdb PS : 0x00060a34 A0 : 0x80010464 A1 : 0x3ffc208c
A2 : 0x3ffcc9e0 A3 : 0x3ffcca20 A4 : 0x04000000 A5 : 0x00000002
A6 : 0x0000000a A7 : 0x00000012 A8 : 0x00000000 A9 : 0x00000001
A10 : 0x00000000 A11 : 0x00000261 A12 : 0x00000069 A13 : 0x3ffd4270
A14 : 0x3ffb9a20 A15 : 0x00000084 SAR : 0x0000001d EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff
Backtrace: 0x40013fd8:0x3ffc208c |<-CORRUPTED
代码如下:
Code: Select all
/**
* @brief 发送 wifi 数据, wifi 发送数据指令格式:
* |-- 目的地址长度(1 byte) --|-- 目的地址(n bytes) --|-- 信息长度(2 bytes) --|-- 目的地址长度(n bytes) --|
* @param[in] data - 发送数据内容
* @param[in] len - 发送数据内容的长度
*/
int tcpClientSendDataToRemote(uint8_t *data, const uint16_t len)
{
char host_ip[17] = {0};
int addr_family = 0;
int ip_protocol = 0;
int sendDataLen = 0;
int toWrite = len;
int written = 0;
int sock = 0;
int err = 0;
if (NULL == data || len < 11 || WifiStation.status != WIFI_STATUS_CONNECTED)
{
return -1;
}
memcpy((uint8_t *)host_ip, (uint8_t *)(data + 1), data[0]);
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = inet_addr(host_ip);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
sock = socket(addr_family, SOCK_STREAM, ip_protocol);
if (sock < 0)
{
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
goto failed;
}
ESP_LOGI(TAG, "Socket created, connecting to %s:%d", host_ip, PORT);
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
err = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
if (err != 0)
{
goto failed;
}
struct linger link;
link.l_onoff = 1;
link.l_linger = 0;
err = setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*)&link, sizeof(link));
if (err != 0)
{
goto failed;
}
err = connect(sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6));
if (err != 0)
{
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
goto failed;
}
ESP_LOGI(TAG, "Successfully connected");
while (toWrite > 0)
{
written = send(sock, (data + len - toWrite), toWrite, 0);
if (written < 0) {
ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
goto failed;
}
toWrite -= written;
}
if (sock != -1)
{
ESP_LOGW(TAG, "Shutting down socket");
shutdown(sock, 0);
close(sock);
}
return 0;
failed:
if (sock != -1)
{
shutdown(sock, 0);
close(sock);
}
return -1;
}