当前位置: 首页 > news >正文

Lwip深度阅读-网络架构

LWIP网络协议栈详细介绍

本文的内容基本基于野火的LWIP手册,和LWIP源码撰写。

网络协议栈概述

从图片可以看出,网络协议栈采用分层架构,每一层都有特定的功能和协议。

TCP/IP协议分层模型

在这里插入图片描述

数据封装过程

在这里插入图片描述

MAC数据包

我使用wireShark抓包的时候,这些MAC的前导包都是不抓的,这些应该在硬件协议上已经完成了,所以抓包抓不到。
在这里插入图片描述

在这里插入图片描述

LWIP架构详解

LWIP (Lightweight IP) 是专为嵌入式系统设计的轻量级TCP/IP协议栈。

LWIP核心特性

// LWIP主要特性
#define LWIP_FEATURES {.memory_efficient = true,        // 内存高效.cpu_efficient = true,          // CPU高效  .modular_design = true,         // 模块化设计.embedded_optimized = true,     // 嵌入式优化.api_multiple = true,          // 多种API接口.protocols_complete = true      // 完整协议支持
}// 内存使用对比
typedef struct {char name[20];uint32_t ram_usage_kb;uint32_t rom_usage_kb;
} tcp_stack_t;tcp_stack_t stacks[] = {{"LWIP",        "8-40",   "30-100"},{"uIP",         "2-8",    "10-30"},{"标准Linux",    "数MB",   "数MB"},{"Windows",     "数十MB", "数十MB"}
};

LWIP架构组件

// LWIP核心组件架构
typedef struct lwip_core {// 网络接口层struct netif *netif_list;          // 网络接口链表// 协议处理层struct {struct tcp_pcb *tcp_active_pcbs;    // TCP活跃连接struct tcp_pcb *tcp_listen_pcbs;    // TCP监听连接struct udp_pcb *udp_pcbs;          // UDP连接struct raw_pcb *raw_pcbs;          // RAW套接字} protocol_cbs;// 内存管理struct {mem_pool_t *mem_pools;             // 内存池pbuf_pool_t *pbuf_pools;           // 数据包缓冲池} memory_mgmt;// 定时器系统struct {sys_timeout_t *timeouts;           // 超时处理uint32_t tcp_timer_interval;       // TCP定时器间隔} timer_sys;} lwip_core_t;// LWIP初始化流程
void lwip_init_sequence(void) {// 1. 内存系统初始化mem_init();memp_init();pbuf_init();// 2. 网络接口初始化  netif_init();// 3. 协议栈初始化ip_init();tcp_init();udp_init();// 4. 应用层协议初始化dhcp_init();dns_init();printf("LWIP协议栈初始化完成\n");
}

协议层详细分析

1. 物理层和数据链路层

// 以太网MAC层实现
typedef struct eth_hdr {uint8_t dest[6];        // 目标MAC地址uint8_t src[6];         // 源MAC地址  uint16_t type;          // 协议类型
} __attribute__((packed)) eth_hdr_t;// 常见协议类型
#define ETHTYPE_IP      0x0800    // IPv4
#define ETHTYPE_ARP     0x0806    // ARP
#define ETHTYPE_IPV6    0x86DD    // IPv6// 以太网帧处理
err_t ethernet_input(struct pbuf *p, struct netif *netif) {struct eth_hdr *ethhdr;uint16_t type;// 检查帧长度if (p->len < sizeof(struct eth_hdr)) {pbuf_free(p);return ERR_BUF;}ethhdr = (struct eth_hdr *)p->payload;type = lwip_ntohs(ethhdr->type);// 移除以太网首部if (pbuf_header(p, -(int16_t)sizeof(struct eth_hdr))) {pbuf_free(p);return ERR_BUF;}// 根据协议类型分发switch (type) {case ETHTYPE_IP:return ip4_input(p, netif);case ETHTYPE_ARP:return etharp_input(p, netif);case ETHTYPE_IPV6:return ip6_input(p, netif);default:pbuf_free(p);return ERR_OK;}
}

2. 网络层 (IP层)

// IP首部结构 (20字节)
typedef struct ip_hdr {uint8_t version_ihl;        // 版本(4位) + 首部长度(4位)uint8_t tos;               // 服务类型uint16_t len;              // 总长度uint16_t id;               // 标识uint16_t offset;           // 标志(3位) + 片偏移(13位)uint8_t ttl;               // 生存时间uint8_t proto;             // 协议类型uint16_t chksum;           // 首部校验和uint32_t src;              // 源IP地址uint32_t dest;             // 目标IP地址
} __attribute__((packed)) ip_hdr_t;// IP协议类型
#define IP_PROTO_ICMP    1     // ICMP协议
#define IP_PROTO_TCP     6     // TCP协议  
#define IP_PROTO_UDP     17    // UDP协议// IP数据包处理
err_t ip4_input(struct pbuf *p, struct netif *inp) {struct ip_hdr *iphdr;uint16_t iphdr_len;uint16_t iphdr_hlen;// 检查IP首部iphdr = (struct ip_hdr *)p->payload;if (IPH_V(iphdr) != 4) {  // 检查IP版本pbuf_free(p);return ERR_OK;}// 获取首部长度iphdr_hlen = IPH_HL(iphdr) * 4;if (iphdr_hlen < IP_HLEN) {pbuf_free(p);return ERR_OK;}// 校验和检查if (inet_chksum(iphdr, iphdr_hlen) != 0) {printf("IP校验和错误\n");pbuf_free(p);return ERR_OK;}// 检查目标地址if (!ip4_addr_isany_val(*netif_ip4_addr(inp)) &&!ip4_addr_cmp(&iphdr->dest, netif_ip4_addr(inp))) {// 不是发给本机的,丢弃或转发pbuf_free(p);return ERR_OK;}// 移除IP首部pbuf_header(p, -(int16_t)iphdr_hlen);// 根据协议类型分发switch (IPH_PROTO(iphdr)) {case IP_PROTO_TCP:return tcp_input(p, inp);case IP_PROTO_UDP:return udp_input(p, inp);case IP_PROTO_ICMP:return icmp_input(p, inp);default:pbuf_free(p);return ERR_OK;}
}

3. 传输层 (TCP/UDP)

// TCP首部结构 (最小20字节)
typedef struct tcp_hdr {uint16_t src;              // 源端口uint16_t dest;             // 目标端口uint32_t seqno;            // 序列号uint32_t ackno;            // 确认号uint16_t hdrlen_rsvd_flags; // 首部长度(4位)+保留(6位)+标志(6位)uint16_t wnd;              // 窗口大小uint16_t chksum;           // 校验和uint16_t urgp;             // 紧急指针
} __attribute__((packed)) tcp_hdr_t;// TCP标志位
#define TCP_FIN  0x01          // 结束连接
#define TCP_SYN  0x02          // 同步序列号
#define TCP_RST  0x04          // 重置连接
#define TCP_PSH  0x08          // 推送数据
#define TCP_ACK  0x10          // 确认
#define TCP_URG  0x20          // 紧急// TCP状态机
typedef enum {CLOSED,        // 关闭状态LISTEN,        // 监听状态SYN_SENT,      // 已发送连接请求SYN_RCVD,      // 已接收连接请求ESTABLISHED,   // 连接已建立FIN_WAIT_1,    // 等待连接终止请求FIN_WAIT_2,    // 等待连接终止CLOSE_WAIT,    // 等待关闭CLOSING,       // 正在关闭LAST_ACK,      // 最后确认TIME_WAIT      // 时间等待
} tcp_state_t;// TCP控制块
struct tcp_pcb {ip_addr_t local_ip;        // 本地IPip_addr_t remote_ip;       // 远程IPuint16_t local_port;       // 本地端口uint16_t remote_port;      // 远程端口tcp_state_t state;         // 连接状态uint32_t snd_nxt;         // 下一个发送序列号uint32_t snd_wl1;         // 段序列号uint32_t snd_wl2;         // 段确认号uint32_t snd_lbb;         // 最后缓冲字节uint16_t snd_wnd;         // 发送窗口uint32_t rcv_nxt;         // 下一个接收序列号uint16_t rcv_wnd;         // 接收窗口uint16_t rcv_ann_wnd;     // 通告窗口// 重传相关struct tcp_seg *unacked;   // 未确认段struct tcp_seg *unsent;    // 未发送段uint16_t rto;             // 重传超时uint8_t nrtx;             // 重传次数// 回调函数tcp_accept_fn accept;      // 接受连接回调tcp_recv_fn recv;         // 接收数据回调tcp_sent_fn sent;         // 发送完成回调tcp_err_fn errf;          // 错误回调
};// TCP三次握手实现
err_t tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr,uint16_t port, tcp_connected_fn connected) {// 设置远程地址和端口ip_addr_copy(pcb->remote_ip, *ipaddr);pcb->remote_port = port;// 生成初始序列号pcb->snd_nxt = tcp_next_iss();pcb->snd_lbb = pcb->snd_nxt - 1;// 设置状态和回调pcb->state = SYN_SENT;pcb->connected = connected;// 发送SYN段return tcp_enqueue_flags(pcb, TCP_SYN);
}

4. 应用层协议

// HTTP服务器实现示例
struct httpd_state {struct tcp_pcb *pcb;char *file;uint32_t left;uint8_t retries;
};// HTTP请求处理
err_t httpd_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {struct httpd_state *hs = (struct httpd_state *)arg;char *data;if (err == ERR_OK && p != NULL) {// 接收HTTP请求tcp_recved(pcb, p->tot_len);data = (char *)p->payload;// 解析HTTP请求行if (strncmp(data, "GET ", 4) == 0) {char *uri = data + 4;char *space = strchr(uri, ' ');if (space) {*space = '\0';printf("HTTP GET: %s\n", uri);// 发送HTTP响应httpd_send_response(pcb, uri);}}pbuf_free(p);tcp_close(pcb);}return ERR_OK;
}// DNS客户端实现
typedef struct dns_query {uint16_t id;               // 查询IDuint16_t flags;            // 标志位uint16_t questions;        // 问题数uint16_t answers;          // 回答数uint16_t authority;        // 权威记录数uint16_t additional;       // 附加记录数
} __attribute__((packed)) dns_hdr_t;void dns_query(const char *hostname, dns_found_callback found, void *arg) {struct pbuf *p;struct dns_hdr *hdr;// 构造DNS查询包p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dns_hdr) + strlen(hostname) + 2 + 4, PBUF_RAM);hdr = (struct dns_hdr *)p->payload;hdr->id = lwip_htons(dns_txid++);hdr->flags = lwip_htons(DNS_FLAG1_RD);  // 递归查询hdr->questions = lwip_htons(1);hdr->answers = 0;hdr->authority = 0;hdr->additional = 0;// 添加查询域名和类型// ... 编码域名和查询类型 ...// 发送UDP包到DNS服务器udp_sendto(dns_pcb, p, &dns_server, DNS_SERVER_PORT);pbuf_free(p);
}

字节序处理

从图片中可以看到字节序的重要性说明:

// 字节序转换宏
#if BYTE_ORDER == BIG_ENDIAN
#define lwip_htons(x) (x)
#define lwip_ntohs(x) (x)
#define lwip_htonl(x) (x)
#define lwip_ntohl(x) (x)
#else
#define lwip_htons(x) ((uint16_t)((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)))
#define lwip_ntohs(x) lwip_htons(x)
#define lwip_htonl(x) ((((x) & 0xff) << 24) | \(((x) & 0xff00) << 8) | \(((x) & 0xff0000UL) >> 8) | \(((x) & 0xff000000UL) >> 24))
#define lwip_ntohl(x) lwip_htonl(x)
#endif// 字节序使用示例
void network_byte_order_example(void) {uint16_t port = 80;uint32_t ip = 0xC0A80101;  // 192.168.1.1// 主机字节序 -> 网络字节序uint16_t net_port = lwip_htons(port);uint32_t net_ip = lwip_htonl(ip);printf("主机字节序端口: %d\n", port);printf("网络字节序端口: 0x%04X\n", net_port);printf("主机字节序IP: 0x%08X\n", ip);printf("网络字节序IP: 0x%08X\n", net_ip);// STM32是小端模式,网络是大端模式,需要转换
}

LWIP内存管理

// LWIP内存池配置
#define MEM_SIZE                (16*1024)    // 堆内存大小
#define MEMP_NUM_PBUF           16           // pbuf数量
#define MEMP_NUM_TCP_PCB        8            // TCP PCB数量
#define MEMP_NUM_UDP_PCB        4            // UDP PCB数量
#define MEMP_NUM_TCP_SEG        16           // TCP段数量// pbuf (packet buffer) 结构
struct pbuf {struct pbuf *next;         // 链表指针void *payload;             // 数据指针uint16_t tot_len;          // 总长度uint16_t len;              // 当前pbuf长度uint8_t type;              // pbuf类型uint8_t flags;             // 标志位uint16_t ref;              // 引用计数
};// pbuf内存分配
struct pbuf *pbuf_alloc(pbuf_layer layer, uint16_t length, pbuf_type type) {struct pbuf *p;uint16_t offset = 0;// 根据层计算偏移switch (layer) {case PBUF_TRANSPORT:offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN;break;case PBUF_IP:offset = PBUF_LINK_HLEN + PBUF_IP_HLEN;break;case PBUF_LINK:offset = PBUF_LINK_HLEN;break;case PBUF_RAW:offset = 0;break;}// 分配内存switch (type) {case PBUF_RAM:p = (struct pbuf *)mem_malloc(sizeof(struct pbuf) + offset + length);if (p) {p->payload = (uint8_t *)p + sizeof(struct pbuf) + offset;}break;case PBUF_POOL:p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL);if (p) {p->payload = (uint8_t *)p + sizeof(struct pbuf) + offset;}break;}if (p) {p->type = type;p->len = p->tot_len = length;p->next = NULL;p->ref = 1;p->flags = 0;}return p;
}

LWIP移植要点

// 1. 系统抽象层 (sys_arch.c)
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"// 信号量实现
err_t sys_sem_new(sys_sem_t *sem, uint8_t count) {*sem = xSemaphoreCreateCounting(255, count);return (*sem != NULL) ? ERR_OK : ERR_MEM;
}void sys_sem_signal(sys_sem_t *sem) {xSemaphoreGive(*sem);
}uint32_t sys_arch_sem_wait(sys_sem_t *sem, uint32_t timeout) {TickType_t start_time = xTaskGetTickCount();if (xSemaphoreTake(*sem, timeout == 0 ? portMAX_DELAY : timeout) == pdTRUE) {return (xTaskGetTickCount() - start_time) * portTICK_PERIOD_MS;}return SYS_ARCH_TIMEOUT;
}// 邮箱实现
err_t sys_mbox_new(sys_mbox_t *mbox, int size) {*mbox = xQueueCreate(size, sizeof(void *));return (*mbox != NULL) ? ERR_OK : ERR_MEM;
}void sys_mbox_post(sys_mbox_t *mbox, void *msg) {xQueueSend(*mbox, &msg, portMAX_DELAY);
}uint32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, uint32_t timeout) {TickType_t start_time = xTaskGetTickCount();if (xQueueReceive(*mbox, msg, timeout == 0 ? portMAX_DELAY : timeout) == pdTRUE) {return (xTaskGetTickCount() - start_time) * portTICK_PERIOD_MS;}return SYS_ARCH_TIMEOUT;
}// 2. 网络接口驱动 (ethernetif.c)
err_t ethernetif_init(struct netif *netif) {// 设置网络接口名称netif->name[0] = 's';netif->name[1] = 't';// 设置网络接口功能netif->output = etharp_output;      // ARP输出netif->linkoutput = low_level_output; // 底层输出// 设置硬件地址netif->hwaddr_len = ETHARP_HWADDR_LEN;netif->hwaddr[0] = 0x02;netif->hwaddr[1] = 0x00;netif->hwaddr[2] = 0x00;netif->hwaddr[3] = 0x00;netif->hwaddr[4] = 0x00;netif->hwaddr[5] = 0x00;// 设置最大传输单元netif->mtu = 1500;// 设置网络接口标志netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET;// 初始化底层硬件low_level_init(netif);return ERR_OK;
}// 底层数据发送
err_t low_level_output(struct netif *netif, struct pbuf *p) {struct pbuf *q;uint8_t *buffer = (uint8_t *)ETH_TX_BUF_BASE;uint32_t len = 0;// 复制pbuf链数据到发送缓冲区for (q = p; q != NULL; q = q->next) {memcpy(buffer + len, q->payload, q->len);len += q->len;}// 启动以太网发送ETH_HandleTypeDef *heth = &EthHandle;while (HAL_ETH_TransmitFrame(heth, len) != HAL_OK) {osDelay(1);}return ERR_OK;
}// 数据接收处理
void ethernetif_input(void const *argument) {struct pbuf *p;struct netif *netif = (struct netif *)argument;while (1) {// 等待接收信号量if (osSemaphoreWait(s_xSemaphore, TIME_WAITING_FOR_INPUT) == osOK) {do {p = low_level_input(netif);if (p != NULL) {// 将数据包传递给协议栈if (netif->input(p, netif) != ERR_OK) {pbuf_free(p);}}} while (p != NULL);}}
}

LWIP配置选项

// lwipopts.h 主要配置选项
#ifndef LWIP_OPTS_H
#define LWIP_OPTS_H// 系统选项
#define NO_SYS                  0           // 使用OS
#define LWIP_SOCKET             1           // 启用socket API
#define LWIP_NETCONN            1           // 启用netconn API// 内存选项
#define MEM_ALIGNMENT           4           // 内存对齐
#define MEM_SIZE                (16*1024)   // 堆大小
#define MEMP_NUM_PBUF           16          // pbuf池大小
#define MEMP_NUM_UDP_PCB        4           // UDP PCB数量
#define MEMP_NUM_TCP_PCB        5           // TCP PCB数量
#define MEMP_NUM_TCP_PCB_LISTEN 4           // TCP监听PCB数量
#define MEMP_NUM_TCP_SEG        16          // TCP段数量
#define MEMP_NUM_REASSDATA      5           // IP重组数据数量
#define MEMP_NUM_FRAG_PBUF      15          // 分片pbuf数量
#define MEMP_NUM_ARP_QUEUE      30          // ARP队列大小
#define MEMP_NUM_IGMP_GROUP     8           // IGMP组数量// ARP选项
#define LWIP_ARP                1           // 启用ARP
#define ARP_TABLE_SIZE          10          // ARP表大小
#define ARP_QUEUEING            1           // ARP队列// IP选项
#define IP_FORWARD              0           // 禁用IP转发
#define IP_OPTIONS_ALLOWED      1           // 允许IP选项
#define IP_REASSEMBLY           1           // IP重组
#define IP_FRAG                 1           // IP分片
#define IP_REASS_MAXAGE         3           // 重组超时
#define IP_REASS_MAX_PBUFS      10          // 重组最大pbuf数
#define IP_FRAG_USES_STATIC_BUF 0           // 分片使用动态缓冲// ICMP选项
#define LWIP_ICMP               1           // 启用ICMP
#define ICMP_TTL                255         // ICMP TTL// DHCP选项
#define LWIP_DHCP               1           // 启用DHCP
#define DHCP_DOES_ARP_CHECK     1           // DHCP ARP检查// UDP选项
#define LWIP_UDP                1           // 启用UDP
#define UDP_TTL                 255         // UDP TTL// TCP选项
#define LWIP_TCP                1           // 启用TCP
#define TCP_TTL                 255         // TCP TTL
#define TCP_WND                 (4*TCP_MSS) // TCP窗口大小
#define TCP_MAXRTX              12          // 最大重传次数
#define TCP_SYNMAXRTX           6           // SYN最大重传次数
#define TCP_QUEUE_OOSEQ         1           // 乱序队列
#define TCP_MSS                 1460        // 最大段长度
#define TCP_CALCULATE_EFF_SEND_MSS 1        // 计算有效MSS
#define TCP_SND_BUF             (2*TCP_MSS) // 发送缓冲区大小
#define TCP_SND_QUEUELEN        (4*TCP_SND_BUF/TCP_MSS) // 发送队列长度
#define TCP_SNDLOWAT            (TCP_SND_BUF/2)          // 发送低水位
#define TCP_LISTEN_BACKLOG      1           // 监听backlog// LWIP调试选项
#define LWIP_DEBUG              1
#define ETHARP_DEBUG            LWIP_DBG_OFF
#define NETIF_DEBUG             LWIP_DBG_OFF
#define PBUF_DEBUG              LWIP_DBG_OFF
#define API_LIB_DEBUG           LWIP_DBG_OFF
#define API_MSG_DEBUG           LWIP_DBG_OFF
#define SOCKETS_DEBUG           LWIP_DBG_OFF
#define ICMP_DEBUG              LWIP_DBG_OFF
#define IGMP_DEBUG              LWIP_DBG_OFF
#define INET_DEBUG              LWIP_DBG_OFF
#define IP_DEBUG                LWIP_DBG_OFF
#define IP_REASS_DEBUG          LWIP_DBG_OFF
#define RAW_DEBUG               LWIP_DBG_OFF
#define MEM_DEBUG               LWIP_DBG_OFF
#define MEMP_DEBUG              LWIP_DBG_OFF
#define SYS_DEBUG               LWIP_DBG_OFF
#define TCP_DEBUG               LWIP_DBG_OFF
#define TCP_INPUT_DEBUG         LWIP_DBG_OFF
#define TCP_FR_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG           LWIP_DBG_OFF
#define TCP_CWND_DEBUG          LWIP_DBG_OFF
#define TCP_WND_DEBUG           LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG        LWIP_DBG_OFF
#define TCP_RST_DEBUG           LWIP_DBG_OFF
#define TCP_QLEN_DEBUG          LWIP_DBG_OFF
#define UDP_DEBUG               LWIP_DBG_OFF
#define TCPIP_DEBUG             LWIP_DBG_OFF
#define PPP_DEBUG               LWIP_DBG_OFF
#define SLIP_DEBUG              LWIP_DBG_OFF
#define DHCP_DEBUG              LWIP_DBG_OFF
#define AUTOIP_DEBUG            LWIP_DBG_OFF
#define SNMP_MSG_DEBUG          LWIP_DBG_OFF
#define SNMP_MIB_DEBUG          LWIP_DBG_OFF
#define DNS_DEBUG               LWIP_DBG_OFF#endif /* LWIP_OPTS_H */

LWIP应用示例

// HTTP客户端示例
void http_client_example(void) {struct netconn *conn;ip_addr_t server_ip;err_t err;// 创建TCP连接conn = netconn_new(NETCONN_TCP);// 设置服务器地址IP4_ADDR(&server_ip, 192, 168, 1, 100);// 连接服务器err = netconn_connect(conn, &server_ip, 80);if (err == ERR_OK) {// 发送HTTP请求char *request = "GET / HTTP/1.1\r\nHost: 192.168.1.100\r\n\r\n";netconn_write(conn, request, strlen(request), NETCONN_COPY);// 接收HTTP响应struct netbuf *buf;err = netconn_recv(conn, &buf);if (err == ERR_OK) {void *data;uint16_t len;netbuf_data(buf, &data, &len);printf("HTTP响应: %.*s\n", len, (char*)data);netbuf_delete(buf);}}// 关闭连接netconn_close(conn);netconn_delete(conn);
}// UDP服务器示例
void udp_server_example(void) {struct netconn *conn;struct netbuf *buf;ip_addr_t *addr;uint16_t port;// 创建UDP连接conn = netconn_new(NETCONN_UDP);// 绑定到本地端口netconn_bind(conn, IP_ADDR_ANY, 8080);printf("UDP服务器启动,监听端口8080\n");while (1) {// 接收数据if (netconn_recv(conn, &buf) == ERR_OK) {addr = netbuf_fromaddr(buf);port = netbuf_fromport(buf);void *data;uint16_t len;netbuf_data(buf, &data, &len);printf("收到来自 %s:%d 的数据: %.*s\n", ip4addr_ntoa(addr), port, len, (char*)data);// 回复数据char *reply = "UDP服务器收到";struct netbuf *reply_buf = netbuf_new();netbuf_alloc(reply_buf, strlen(reply));memcpy(netbuf_data(reply_buf, NULL, NULL), reply, strlen(reply));netconn_sendto(conn, reply_buf, addr, port);netbuf_delete(reply_buf);netbuf_delete(buf);}}
}

LWIP是一个功能强大且高效的轻量级TCP/IP协议栈,特别适合资源受限的嵌入式系统。它提供了完整的网络协议支持,同时保持了较小的内存占用和良好的性能表现。通过合理的配置和移植,可以在各种嵌入式平台上实现可靠的网络通信功能。

目前打算从LWIP的内存管理,内核API线程调用,网络层,传输层,应用层分别撰写。目前仅仅作为初始起步各层的简易介绍

http://www.dtcms.com/a/326715.html

相关文章:

  • 【代码随想录day 17】 力扣 654.最大二叉树
  • 贪心----2.跳跃游戏
  • 区块链技术原理(5)-网络
  • Docker部署MySQL完整指南:从入门到实践
  • Leetcode-25.K个一组翻转链表
  • 【13-向量化-高效计算】
  • 第二十一天:统计数字
  • 嵌入式系统学习Day16(C语言中的位运算)
  • 绿巨人VS Code多开项目单独管理每个项目单独使用一个不限制的augment
  • 构建AI代理工作流的开源利器——Sim Studio
  • 文件编辑html
  • C语言命令行参数
  • 北京JAVA基础面试30天打卡07
  • 【C++竞赛】核桃CSP-J模拟赛题解
  • 提示词工程实战:用角色扮演让AI输出更专业、更精准的内容
  • vagrant和itamae怎么配合使用? (放弃)
  • 33Nginx模块的从配置与优化
  • 如何使用curl编程来下载文件
  • MacBook 本地化部署 Dify 指南
  • AIDL简单使用
  • 【接口自动化测试】---YAML、JSON Schema
  • 逐际动力开源运控 tron1-rl-isaacgym 解读与改进
  • VMD例程(Matlab 2021b可直接使用)
  • 从“目标烂尾”到“100%交付”:谷歌OKR追踪系统如何用“透明化+强问责”打造职场责任闭环
  • 小白入门指南:Edge SCDN 轻松上手
  • Dify 从入门到精通(第 28/100 篇):Dify 的多租户架构
  • 【学习嵌入式day-21-Linux编程-shell命令】
  • 第九篇:调试工具:Three.js Inspector使用
  • 武汉火影数字|VR大空间是什么?如何打造VR大空间项目
  • 【华为机试】648. 单词替换