Fetch the repository succeeded.
同样的TCP服务端代码,在Linux服务器上可以测试通过,在Hi3861上accept
失败,errno = 12;
是lwip编译时候配置的内存小了吗?
===============================================================
测试代码如下:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#if defined(__linux__)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#else // __linux__
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifi_device.h"
#include "lwip/sockets.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#define close(fd) lwip_close(fd)
#define PARAM_HOTSPOT_SSID "ABCD" // your AP SSID
#define PARAM_HOTSPOT_PSK "12345678" // your AP PSK
#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK // defined in wifi_device_config.h
#endif // __linux__
#define PARAM_SERVER_PORT 5678
static char request[128] = "";
static ssize_t TcpServerTest(unsigned short port)
{
ssize_t retval = 0;
int backlog = 1;
int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket
int connfd = -1;
socklen_t clientAddrLen = 0;
struct sockaddr_in clientAddr = {0};
struct sockaddr_in serverAddr = {0};
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
retval = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
if (retval < 0) {
printf("bind failed, %ld!\r\n", retval);
goto do_cleanup;
}
printf("bind to port %d success!\r\n", port);
retval = listen(sockfd, backlog);
if (retval < 0) {
printf("listen failed!\r\n");
goto do_cleanup;
}
printf("listen with %d backlog success!\r\n", backlog);
connfd = accept(sockfd, (struct sockaddr *)&clientAddr, &clientAddrLen);
if (connfd < 0) {
printf("accept failed, %d, %d\r\n", connfd, errno);
goto do_cleanup;
}
printf("accept success, connfd = %d!\r\n", connfd);
retval = recv(connfd, request, sizeof(request), 0);
if (retval < 0) {
printf("recv request failed, %ld!\r\n", retval);
goto do_disconnect;
}
printf("recv request{%s} from client done!\r\n", request);
retval = send(connfd, request, strlen(request), 0);
if (retval <= 0) {
printf("send response failed, %ld!\r\n", retval);
goto do_disconnect;
}
printf("send response{%s} to client done!\r\n", request);
do_disconnect:
sleep(1);
close(connfd);
sleep(1); // for debug
do_cleanup:
printf("do_cleanup...\r\n");
close(sockfd);
return retval;
}
#if defined(__linux__)
int main(int argc, char* argv[])
{
unsigned short port = argc > 1 ? atoi(argv[1]) : PARAM_SERVER_PORT;
TcpServerTest(port);
return 0;
}
#else // __linux__
static void PrintLinkedInfo(WifiLinkedInfo* info)
{
if (!info) return;
static char macAddress[32] = {0};
unsigned char* mac = info->bssid;
snprintf(macAddress, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
printf("bssid: %s, rssi: %d, connState: %d, reason: %d, ssid: %s\r\n",
macAddress, info->rssi, info->connState, info->disconnectedReason, info->ssid);
}
static volatile int g_connected = 0;
static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
{
if (!info) return;
printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
PrintLinkedInfo(info);
if (state == WIFI_STATE_AVALIABLE) {
g_connected = 1;
} else {
g_connected = 0;
}
}
static void OnWifiScanStateChanged(int state, int size)
{
printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
}
static WifiEvent g_defaultWifiEventListener = {
.OnWifiConnectionChanged = OnWifiConnectionChanged,
.OnWifiScanStateChanged = OnWifiScanStateChanged
};
static struct netif* g_iface = NULL;
int ConnectToHotspot(WifiDeviceConfig* apConfig)
{
WifiErrorCode errCode;
int netId = -1;
errCode = RegisterWifiEvent(&g_defaultWifiEventListener);
printf("RegisterWifiEvent: %d\r\n", errCode);
errCode = EnableWifi();
printf("EnableWifi: %d\r\n", errCode);
errCode = AddDeviceConfig(apConfig, &netId);
printf("AddDeviceConfig: %d\r\n", errCode);
g_connected = 0;
errCode = ConnectTo(netId);
printf("ConnectTo(%d): %d\r\n", netId, errCode);
while (!g_connected) { // wait until connect to AP
osDelay(10);
}
printf("g_connected: %d\r\n", g_connected);
g_iface = netifapi_netif_find("wlan0");
if (g_iface) {
err_t ret = netifapi_dhcp_start(g_iface);
printf("netifapi_dhcp_start: %d\r\n", ret);
osDelay(100); // wait DHCP server give me IP
ret = netifapi_netif_common(g_iface, dhcp_clients_info_show, NULL);
printf("netifapi_netif_common: %d\r\n", ret);
}
return netId;
}
void DisconnectWithHotspot(int netId)
{
if (g_iface) {
err_t ret = netifapi_dhcp_stop(g_iface);
printf("netifapi_dhcp_stop: %d\r\n", ret);
}
WifiErrorCode errCode = Disconnect(); // disconnect with your AP
printf("Disconnect: %d\r\n", errCode);
errCode = UnRegisterWifiEvent(&g_defaultWifiEventListener);
printf("UnRegisterWifiEvent: %d\r\n", errCode);
RemoveDevice(netId); // remove AP config
printf("RemoveDevice: %d\r\n", errCode);
errCode = DisableWifi();
printf("DisableWifi: %d\r\n", errCode);
}
static void TcpServerTask(void *arg)
{
(void)arg;
WifiDeviceConfig config = {0};
// 准备AP的配置参数
strcpy(config.ssid, PARAM_HOTSPOT_SSID);
strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);
config.securityType = PARAM_HOTSPOT_TYPE;
osDelay(10);
int netId = ConnectToHotspot(&config);
int timeout = 10;
while (timeout--) {
printf("After %d seconds, I will start TCP server test!\r\n", timeout);
osDelay(100);
}
TcpServerTest(PARAM_SERVER_PORT);
printf("disconnect to AP ...\r\n");
DisconnectWithHotspot(netId);
printf("disconnect to AP done!\r\n");
}
static void TcpServerDemo(void)
{
osThreadAttr_t attr;
attr.name = "TcpServerTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 4096;
attr.priority = osPriorityNormal;
if (osThreadNew(TcpServerTask, NULL, &attr) == NULL) {
printf("[TcpServerDemo] Falied to create TcpServerTask!\n");
}
}
SYS_RUN(TcpServerDemo);
#endif // __linux__
===============================================================
Linux上编译:
gcc tcp_srever_test.c
Linux上运行服务端:
./a.out
Linux上运行客户端,可以成功连接上服务端:
$ nc localhost 5678
asdf
asdf
===============================================================
Hi3861开发版上运行结果:
[23:29:37.181]收←◆ready to OS start
sdk ver:Hi3861V100R001C00SPC025 2020-09-03 18:10:00
formatting spiffs...
[23:29:37.528]收←◆FileSystem mount ok.
wifi init success!
00 00:00:00 0 68 D 0/HIVIEW: hilog init success.
00 00:00:00 0 68 D 0/HIVIEW: log limit init success.
00 00:00:00 0 68 I 1/SAMGR: Bootstrap core services(count:3).
00 00:00:00 0 68 I 1/SAMGR: Init service:0x4af8c8 TaskPool:0xfb7c8
00 00:00:00 0 68 I 1/SAMGR: Init service:0x4af8ec TaskPool:0xfbe38
00 00:00:00 0 68 I 1/SAMGR: Init service:0x4af9fc TaskPool:0xfbff8
00 00:00:00 0 200 I 1/SAMGR: Init service 0x4af8ec <time: 0ms> success!
00 00:00:00 0 100 I 1/SAMGR: Init service 0x4af8c8 <time: 0ms> success!
00 00:00:00 0 44 D 0/HIVIEW: hiview init success.
00 00:00:00 0 44 I 1/SAMGR: Init service 0x4af9fc <time: 0ms> success!
00 00:00:00 0 44 I 1/SAMGR: Initialized all core system services!
00 00:00:00 0 100 I 1/SAMGR: Bootstrap system and application services(count:0).
00 00:00:00 0 100 I 1/SAMGR: Initialized all system and application services!
00 00:00:00 0 100 I 1/SAMGR: Bootstrap dynamic registered services(count:0).
[23:29:37.706]收←◆RegisterWifiEvent: 0
EnableWifi: 0
AddDeviceConfig: 0
[23:29:38.138]收←◆ConnectTo(0): 0
[23:29:38.911]收←◆+NOTICE:SCANFINISH
+NOTICE:CONNECTED
OnWifiConnectionChanged 120, state = 1, info =
bssid: 70:C9:4E:E3:00:4B, rssi: 0, connState: 0, reason: 0, ssid: ABCD
[23:29:39.030]收←◆g_connected: 1
netifapi_dhcp_start: 0
[23:29:40.031]收←◆server :
server_id : 192.168.137.1
mask : 255.255.255.0, 1
gw : 192.168.137.1
T0 : 604800
T1 : 300
T2 : 453600
clients <1> :
mac_idx mac addr state lease tries rto
0 b4c9b9af6903 192.168.137.56 10 0 1 4
netifapi_netif_common: 0
After 9 seconds, I will start TCP server test!
[23:29:41.051]收←◆After 8 seconds, I will start TCP server test!
[23:29:42.050]收←◆After 7 seconds, I will start TCP server test!
[23:29:43.050]收←◆After 6 seconds, I will start TCP server test!
[23:29:44.050]收←◆After 5 seconds, I will start TCP server test!
[23:29:45.050]收←◆After 4 seconds, I will start TCP server test!
[23:29:46.051]收←◆After 3 seconds, I will start TCP server test!
[23:29:47.050]收←◆After 2 seconds, I will start TCP server test!
[23:29:48.050]收←◆After 1 seconds, I will start TCP server test!
[23:29:49.050]收←◆After 0 seconds, I will start TCP server test!
[23:29:50.051]收←◆bind to port 5678 success!
listen with 1 backlog success!
[23:29:53.805]发→◇AT+SYSINFO
□
[23:29:53.810]收←◆AT+SYSINFO
+SYSINFO:
mem:
total=211264,used=81212,free=130052,peek_size=86020
os_resource:
timer_usage=15,task_usage=12,sem_usage=7,queue_usage=4,mux_usage=21,event_usage=3
task_info:
Swt_Task,id=0,status=8192,pri=0,size=0x800,cur_size=0x100,peak_size=0x174
IdleCore000,id=1,status=4,pri=31,size=0x400,cur_size=0xb0,peak_size=0x124
wpa_supplicant,id=2,status=8,pri=4,size=0x1800,cur_size=0x1a0,peak_size=0x9e0
flash_prot,id=3,status=8,pri=1,size=0x400,cur_size=0x100,peak_size=0x174
at_proc,id=4,status=20,pri=10,size=0xc00,cur_size=0x2d0,peak_size=0x5a4
at_uart,id=5,status=8,pri=9,size=0x600,cur_size=0x160,peak_size=0x1e4
tcpip_thread,id=6,status=72,pri=5,size=0x1000,cur_size=0x1e0,peak_size=0x480
hisi_frw,id=7,status=8,pri=4,size=0xc00,cur_size=0x100,peak_size=0x660
TcpServerTask,id=9,status=8,pri=15,size=0x1000,cur_size=0x310,peak_size=0x880
Bootstrap,id=10,status=8192,pri=14,size=0x800,cur_size=0x190,peak_size=0x340
Broadcast,id=11,status=8192,pri=7,size=0x800,cur_size=0x190,peak_size=0x260
hiview,id=12,status=8192,pri=15,size=0x800,cur_size=0x190,peak_size=0x5a0
cpup:
runtime:
0d-00h-00m-16s
OK
[23:30:01.149]发→◇AT+IFCFG
□
[23:30:01.153]收←◆AT+IFCFG
+IFCFG:wlan0,ip=192.168.137.56,netmask=255.255.255.0,gateway=192.168.137.1,ip6=FE80::B6C9:B9FF:FEAF:6903,HWaddr=b4:c9:b9:af:69:03,MTU=1500,LinkStatus=1,RunStatus=1
+IFCFG:lo,ip=127.0.0.1,netmask=255.0.0.0,gateway=127.0.0.1,ip6=::1,HWaddr=00,MTU=16436,LinkStatus=1,RunStatus=1
OK
[23:30:18.441]收←◆accept failed, -1, 12
do_cleanup...
disconnect to AP ...
netifapi_dhcp_stop: 0
+NOTICE:DISCONNECTED
OnWifiConnectionChanged 120, state = 0, info =
bssid: 70:C9:4E:E3:00:4B, rssi: 0, connState: 0, reason: 3, ssid:
Disconnect: 0
UnRegisterWifiEvent: 0
RemoveDevice: 0
DisableWifi: 0
disconnect to AP done!
accpet会阻塞,直到PC上启动客户端测试连接命令:
$ nc 192.168.137.56 5678
12345
PC上客户端命令刚启动,板子上就会 accept failed
查了 lwip/errno.h
,错误码12是:
#define ENOMEM 12 /* Out of memory */
但是,我通过SYSINFO查询到,系统还有空闲内存可用