API
推荐在Socket层面的API,一共只有如下这么多:
#include “socket.h”
int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);
int lwip_shutdown(int s, int how);
int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);
int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);
int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
int lwip_close(int s);
int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
int lwip_listen(int s, int backlog);
ssize_t lwip_recv(int s, void *mem, size_t len, int flags);
ssize_t lwip_read(int s, void *mem, size_t len);
ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt);
ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
ssize_t lwip_recvmsg(int s, struct msghdr *message, int flags);
ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags);
ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags);
ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen);
int lwip_socket(int domain, int type, int protocol);
ssize_t lwip_write(int s, const void *dataptr, size_t size);
ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt);
#if LWIP_SOCKET_SELECT
int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
struct timeval *timeout);
#endif
#if LWIP_SOCKET_POLL
int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout);
#endif
int lwip_ioctl(int s, long cmd, void *argp);
int lwip_fcntl(int s, int cmd, int val);
const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size);
int lwip_inet_pton(int af, const char *src, void *dst);
流程
如果做client,操作流程如下
API | 功能描述 |
---|---|
server_fd = lwip_socket( ) | 新建socket描述符 |
lwip_connect( server_addr ) | 连接服务器 |
lwip_read( server_fd ) | 接收数据 |
lwip_write( server_fd ) | 发送数据 |
如果做server,操作流程如下
API | 功能描述 |
---|---|
server_fd = lwip_socket( ) | 新建socket描述符 |
lwip_bind( server_fd, server_addr ) | 分配套接字地址 |
lwip_listen( server_fd ) | 等待连接请求状态 |
lwip_accept( server_fd, client_addr ) | 允许连接 |
lwip_read( client_addr ) | 接收数据 |
lwip_write( client_addr) | 发送数据 |
lwip_recvfrom( client_addr ) | 接收数据,可以获取到接收数据是谁发出的 |
sockaddr_in 初始化
struct sockaddr_in {
u8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
#define SIN_ZERO_LEN 8
char sin_zero[SIN_ZERO_LEN];
};
参数 | 意义 | 初始化实例 |
---|---|---|
sin_family | 协议族 | server_addr.sin_family = AF_INET; |
sin_port | 端口号 | server_addr.sin_port = htons(49850); htons( ):16位数据字节交换 |
sin_addr | IP地址 | server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_addr.s_addr = inet_addr(“192.168.0.5”); INADDR_ANY:000000000,代表所有网卡 htonl( ):32位数据字节交换 inet_addr( ):字符串IP地址转网络序IP地址 |
其他参数 | 全部清零 |
示例
TCP server send
int ret; //保存lwip api返回值,一般来说不是-1就没问题
int server_fd; //保存socket描述符,由lwip_socket返回,如果是-1那么描述符分配失败
struct sockaddr_in server_addr; //保存socket相应的地址和端口号
int client_fd = 0;
struct sockaddr_in client_addr; //保存socket相应的地址和端口号
uint32_t client_addr_sz = 0;
restart:
server_fd = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); //IPV4,TCP,IP
PROJ_ASSERT(server_fd != -1);
memset(&server_addr, 0, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET; //IPV4
server_addr.sin_port = htons(49850); //htons用于交换port高低字节
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //htonl用于交换s_addr高低字节
osDelay(10);
ret = lwip_bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
if(ret == -1)goto err;
ret = lwip_listen(server_fd, 0);
if(ret == -1)goto err;
reaccept:
client_fd = lwip_accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_sz);
PROJ_ASSERT(client_fd != -1);
for(;;)
{
ret = lwip_write(client_fd, "hello from lwip_func\n", sizeof("hello from lwip_func\n"));
if(ret == -1)
{
lwip_close(client_fd);
goto reaccept;
}
osDelay(100);
}
err:
lwip_close(server_fd);
goto restart;