Q群:
电话:
邮箱:
地址:
OneOS socket组件为用户提供了一套兼容BSD的标准接口,用来实现网络连接及数据传输,下层涵盖了以太模块、蜂窝模组和wifi模组等不同制式的通信介质以及不同的通信协议栈。以太模块使用lwip协议栈,蜂窝模组和wifi模组使用at指令进行拨号连接和数据收发。
使用限制:标准socket组件使用时lwip和at只能二选一,在编译配置时决定。
(Top) → Components→ Network→ Socket
OneOS Configuration
[*] Enable BSD socket API
protocol stack implement (Support OneOS modules stack) --->
(Top) → Osal→ POSIX compatibility layer
OneOS Configuration
[ ] Enable pthreads
[*] Enable POSIX layer for poll/select, stdin etc
[ ] Enable mmap
[ ] Enable termios feature
[ ] Enable aio
Enable POSIX layer for poll/select, stdin etc配置项影响select函数的实现,如果启用POSIX,select实现基于vfs的poll机制;如果不启用POSIX,select由molink或者lwip单独实现。
以ESP8266配置举例,Enable * BSD Socket Operates必须启用
(Top) → Components → Network → Molink → Enable IoT modules support → Modules → WiFi Modules Support → ESP8266 → ESP8266 Config
OneOS Configuration
[*] Enable ESP8266 Module Object Auto Create
(uart2) ESP8266 Interface Device Name
(115200) ESP8266 Interface Device Rate
(512) The maximum length of AT command data accepted
[*] Enable ESP8266 Module Auto Connect
(hw_hsj) ESP8266 Connect AP SSID
(Aa123456) ESP8266 Connect AP Password
[*] Enable ESP8266 Module General Operates
-*- Enable ESP8266 Module WiFi Operates
[*] Enable ESP8266 Module Network Service Operates
-*- Enable ESP8266 Module Network TCP/IP Operates
[*] Enable ESP8266 Module BSD Socket Operates
(Top) → Components → Networ→ LwIP
OneOS Configuration
[*] Enable lwIP stack
lwIP version (lwIP v2.1.2) --->
[*] IGMP protocol (NEW)
[*] ICMP protocol (NEW)
[ ] SNMP protocol (NEW)
[*] Enble DNS for name resolution (NEW)
[*] Enable alloc ip address through DHCP (NEW)
(1) SOF broadcast (NEW)
(1) SOF broadcast recv (NEW)
[ ] Enable DHCP server (NEW)
Static IPv4 Address --->
-*- UDP protocol (NEW)
[*] TCP protocol (NEW)
[ ] RAW protocol (NEW)
[ ] PPP protocol (NEW) ||||
包含标准的socket头文件即可,如
#include <atest.h>
#include <shell.h>
#include <os_kernel.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#ifdef OS_USING_POSIX
#include <sys/select.h>
#endif
#include <os_mutex.h>
#include <os_dbg_ext.h>
os_task_t *gs_socket_select_task = OS_NULL;
int gs_select_fd = -1;
os_mutex_t *gs_socket_mutex = OS_NULL;
static void socket_dump_hex(const os_uint8_t *ptr, os_size_t buflen)
{
unsigned char *buf;
int i;
int j;
buf = (unsigned char *)ptr;
for (i = 0; i < buflen; i += 16)
{
os_kprintf("%08X: ", i);
for (j = 0; j < 16; j++)
{
if (i + j < buflen)
{
os_kprintf("%02X ", buf[i + j]);
}
else
{
os_kprintf(" ");
}
}
os_kprintf("\n");
}
}
static void socket_do_select_task(void *parm)
{
os_uint8_t recv_buf[128];
fd_set readfds;
fd_set exfds;
int maxfd;
int err;
int fd;
while (1)
{
os_mutex_lock(gs_socket_mutex, OS_IPC_WAITING_FOREVER);
if (gs_select_fd < 0)
{
os_mutex_unlock(gs_socket_mutex);
os_task_sleep(100);
continue;
}
fd = gs_select_fd;
maxfd = fd + 1;
os_mutex_unlock(gs_socket_mutex);
do
{
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
FD_ZERO(&exfds);
FD_SET(fd, &exfds);
err = select(maxfd, &readfds, OS_NULL, OS_NULL, OS_NULL);
if (err > 0)
{
if (FD_ISSET(fd, &readfds))
{
err = recv(fd, recv_buf, sizeof(recv_buf), 0);
os_kprintf("recv len[%d]\n", err);
if (err > 0)
{
socket_dump_hex(recv_buf, err);
}
else
{
os_mutex_lock(gs_socket_mutex, OS_IPC_WAITING_FOREVER);
if(gs_select_fd >= 0)
{
closesocket(gs_select_fd);
gs_select_fd = -1;
}
os_mutex_unlock(gs_socket_mutex);
break;
}
}
}
os_mutex_lock(gs_socket_mutex, OS_IPC_WAITING_FOREVER);
if (gs_select_fd != fd)
{
os_mutex_unlock(gs_socket_mutex);
break;
}
os_mutex_unlock(gs_socket_mutex);
} while (err >= 0);
os_task_sleep(5);
}
}
static int socket_cmd_select_init(void)
{
if (OS_NULL == gs_socket_mutex)
{
gs_socket_mutex = os_mutex_create("slt_mtx", OS_IPC_FLAG_FIFO, OS_FALSE);
}
if (OS_NULL == gs_socket_mutex)
{
os_kprintf("mutex failed\n");
return OS_ERROR;
}
if (OS_NULL == gs_socket_select_task)
{
gs_socket_select_task = os_task_create("slt_task", socket_do_select_task,
OS_NULL, 1024, OS_TASK_PRIORITY_MAX - 5, 5);
if (OS_NULL != gs_socket_select_task)
{
(void)os_task_startup(gs_socket_select_task);
}
else
{
os_kprintf("select task create failed\n");
return OS_ERROR;
}
}
return OS_EOK;
}
static int socket_cmd_socket_select(int argc, char **argv)
{
struct sockaddr_in server_addr;
char send_buf[] = "hello world";
int type;
int flag;
int port;
int err;
if (argc != 5)
{
os_kprintf("Input errror, please input: socket_select flag ip port type\n");
return OS_ERROR;
}
err = socket_cmd_select_init();
if (OS_EOK != err)
{
os_kprintf("Do socket select init failed\n");
return OS_ERROR;
}
flag = atoi(argv[1]);
port = atoi(argv[3]);
if (!strcmp(argv[4], "udp"))
{
type = SOCK_DGRAM;
}
else if (!strcmp(argv[4], "tcp"))
{
type = SOCK_STREAM;
}
else
{
type = SOCK_RAW;
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = inet_addr(argv[2]);
if (!flag)
{
os_kprintf("stop socket select fd = %d\n", gs_select_fd);
os_mutex_lock(gs_socket_mutex, OS_IPC_WAITING_FOREVER);
if (gs_select_fd >= 0)
{
closesocket(gs_select_fd);
gs_select_fd = -1;
}
os_mutex_unlock(gs_socket_mutex);
}
else
{
os_mutex_lock(gs_socket_mutex, OS_IPC_WAITING_FOREVER);
if (gs_select_fd >= 0)
{
os_mutex_unlock(gs_socket_mutex);
os_kprintf("socket select fd = %d is already exist\n", gs_select_fd);
return OS_EOK;
}
gs_select_fd = socket(AF_INET, type, 0);
if (gs_select_fd < 0)
{
os_mutex_unlock(gs_socket_mutex);
os_kprintf("why socket failed = %d\n", gs_select_fd);
return OS_ERROR;
}
err = connect(gs_select_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
if (err < 0)
{
os_kprintf("connect socket =%d failed\n", gs_select_fd);
closesocket(gs_select_fd);
gs_select_fd = -1;
os_mutex_unlock(gs_socket_mutex);
return OS_ERROR;
}
if (SOCK_DGRAM == type)
{
err = sendto(gs_select_fd, send_buf, sizeof(send_buf), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
os_kprintf("udp[fd = %d] send = %d\n", gs_select_fd, err);
}
os_mutex_unlock(gs_socket_mutex);
}
return OS_EOK;
}
SH_CMD_EXPORT(socket_select, socket_cmd_socket_select, "socket_select 1/0 ipaddr port tcp/udp");