socket即“套接字”,是网络通信的一种方式,在microLite裸机系统编程中如何使用socket API进行数据通信呢?microLite以lwip协议栈为基础,实现了一组极简版udp socket裸机API接口。
socket框架
socket API接口是网络驱动层提供给应用程序编程的接口。
microLite socket框架如下图:
socket接口
microLite支持的socket接口包括:
- MLSocket.Init,初始化以太网驱动,协议栈等;
- MLSocket.sock,打开(创建)一个socket;
- MLSocket.bind,将socket和一个端口绑定;
- MLSocket.setsockopt,设置socket选项;
- MLSocket.sendto,发送message到socket;
- MLSocket.recvfrom,从socket接收message;
- MLSocket.Run,循环执行以太网协议栈。
socket接口采用非阻塞方式收发数据,API接口MLSocket.recvfrom的返回值表示接收的字节个数。
socket接口范例
socket编程涉及到的需求多种多样,这里仅列出几种接口编程范例。另外,MLKernel的初始化以及MLSocket的初始化在进入main之前设置,这里不做介绍。
笔记本IP:192.168.6.199;
单片机IP:192.168.6.60。
(1)需求:单片机定时发送信息“hello world!!!”至笔记本的17111端口
#include "ml_kernel.h"
#include "ml_socket.h"
int socket_fd1 = -1;
/* 初始化内核等在进入main之前完成 */
int main(void)
{
struct sockaddr_in local_addr = {
0};
if ((socket_fd1 = MLSocket.sock(ML_PROTO_UDP)) < 0) {
ML_USR_LOG(ML_LOG_ERR, "create socket failed");
}
while (1) {
MLKernel.Run();
MLSocket.Run();
if (MLKernel.TimeDly(1000)) {
char hello[] = "hello world!!!";
struct sockaddr_in dest_addr = {
0};
dest_addr.sin_port = 17111;
dest_addr.sin_addr.s_addr = htonl(LWIP_MAKEU32(192, 168, 6, 199));
MLSocket.sendto(socket_fd1, \
(uint8_t *)hello, sizeof(hello), \
&dest_addr);
}
}
}
PC端如下图,其中49154为随机端口。
(2)需求:单片机定时发送信息“hello world!!!”至笔记本的17111端口,单片机的1111端口能接收笔记本发来的信息。
#include "ml_kernel.h"
#include "ml_socket.h"
int socket_fd1 = -1;
int main(void)
{
printf("this is an example about microLite socket \r\n");
struct sockaddr_in local_addr = {
0};
if ((socket_fd1 = MLSocket.sock(ML_PROTO_UDP)) < 0) {
ML_USR_LOG(ML_LOG_ERR, "create socket failed");
}
local_addr.sin_port = 1111;
local_addr.sin_addr.s_addr = htonl(LWIP_MAKEU32(0, 0, 0, 0));
/* This API is used to create socket and bind local ip and port */
if ((socket_fd1 = MLSocket.bind(socket_fd1, (const struct