Files

147 lines
4.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "plat_comm/lwip_module/lwip_module.h"
#include "lwip/sockets.h" /* LwIP socket APIsocket/connect/send/recv/close */
#include "lwip/netdb.h" /* 域名解析 lwip_gethostbyname */
#include <string.h>
#include <errno.h>
/**
* ************************************************************************
* @brief 将主机名或 IP 字符串解析为 in_addr
* @param[in] host - 服务器地址,可为 "192.168.1.1" 或 "www.xxx.com"
* @param[out] out_addr - 解析得到的 IPv4 地址
* @return 0 成功,-1 失败(非 IP 且 DNS 解析失败)
* ************************************************************************
*/
int lwip_resolve_host(const char *host, struct in_addr *out_addr)
{
if (host == NULL || out_addr == NULL)
return -1;
/* 先按 IP 字符串解析(如 "134.17.16.109" */
unsigned long addr = inet_addr(host);
if (addr != INADDR_NONE) {
out_addr->s_addr = addr;
return 0;
}
/* 非 IP 则按域名解析(依赖 LwIP DNS,仅 LWIP_DNS=1 时 netdb.h 才声明 lwip_gethostbyname */
#if LWIP_DNS
{
struct hostent *he = lwip_gethostbyname(host);
if (he != NULL && he->h_addr_list[0] != NULL) {
memcpy(&out_addr->s_addr, he->h_addr_list[0], (size_t)he->h_length);
return 0;
}
}
#endif
return -1;
}
/**
* ************************************************************************
* @brief 设置 socket 为非阻塞模式
* @param[in] sock - socket 描述符
* @return 0 成功,-1 失败
* ************************************************************************
*/
int lwip_set_nonblock(int sock)
{
int flags = lwip_fcntl(sock, F_GETFL, 0);
if (flags >= 0) {
if (lwip_fcntl(sock, F_SETFL, flags | O_NONBLOCK) >= 0)
return 0;
}
return -1;
}
/**
* ************************************************************************
* @brief 创建 TCP socket 并连接到指定地址
* @param[in] host - 服务器地址(IP 或域名)
* @param[in] port - 服务器端口
* @return >=0 socket 描述符,<0 失败
* ************************************************************************
*/
int lwip_tcp_connect(const char *host, uint16_t port)
{
struct sockaddr_in server_addr;
struct in_addr ip_addr;
int sock;
if (host == NULL || host[0] == '\0' || port == 0)
return -1;
/* 创建 TCP 流式 socket */
sock = lwip_socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
return -1;
/* 解析服务器 hostIP 或域名)为 in_addr */
if (lwip_resolve_host(host, &ip_addr) != 0) {
lwip_close(sock);
return -1;
}
/* 填充服务器地址并发起连接 */
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = ip_addr.s_addr;
server_addr.sin_port = htons(port);
if (lwip_connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) {
lwip_close(sock);
return -1;
}
/* 设为非阻塞,避免 recv 阻塞任务 */
if (lwip_set_nonblock(sock) != 0) {
lwip_close(sock);
return -1;
}
return sock;
}
/**
* ************************************************************************
* @brief 关闭 socket
* @param[in] sock - socket 描述符
* ************************************************************************
*/
void lwip_tcp_close(int sock)
{
if (sock >= 0)
lwip_close(sock);
}
/**
* ************************************************************************
* @brief 发送数据
* @param[in] sock - socket 描述符
* @param[in] buf - 发送缓冲区
* @param[in] len - 发送长度
* @return >0 实际发送字节数,<=0 失败或对端关闭
* ************************************************************************
*/
int lwip_tcp_send(int sock, const void *buf, size_t len)
{
if (sock < 0 || buf == NULL || len == 0)
return -1;
return lwip_send(sock, buf, len, 0);
}
/**
* ************************************************************************
* @brief 接收数据(非阻塞)
* @param[in] sock - socket 描述符
* @param[out] buf - 接收缓冲区
* @param[in] len - 缓冲区长度
* @return >0 实际接收字节数,0 对端关闭,<0 错误(errno 需检查)
* ************************************************************************
*/
int lwip_tcp_recv(int sock, void *buf, size_t len)
{
if (sock < 0 || buf == NULL || len == 0)
return -1;
return lwip_recv(sock, buf, len, 0);
}