[{"data":1,"prerenderedAt":974},["ShallowReactive",2],{"doc-\u002Fdocs\u002Fapi\u002Feduwin-net-api":3},{"id":4,"title":5,"body":6,"description":43,"extension":968,"meta":969,"navigation":177,"path":970,"seo":971,"stem":972,"__hash__":973},"content\u002Fdocs\u002Fapi\u002Feduwin-net-api.md","eduwin 网络模块 API",{"type":7,"value":8,"toc":950},"minimark",[9,13,29,32,37,72,95,115,119,128,139,159,163,264,284,329,333,377,394,398,452,462,496,500,509,512,516,519,523,539,543,567,576,579,604,636,640,680,715,718,770,773,905,908,918,921,924,932,935,946],[10,11,5],"h1",{"id":12},"eduwin-网络模块-api",[14,15,16],"blockquote",{},[17,18,19,20,24,25,28],"p",{},"头文件：",[21,22,23],"code",{},"eduwin_net.h","（或通过 ",[21,26,27],{},"eduwin.h"," 统一引用）",[17,30,31],{},"基于 Winsock2 + WinHTTP，零外部依赖。提供 TCP、UDP、HTTP、DNS 四层能力。",[33,34,36],"h2",{"id":35},"初始化-清理","初始化 \u002F 清理",[38,39,44],"pre",{"className":40,"code":41,"language":42,"meta":43,"style":43},"language-c shiki shiki-themes github-light github-dark","int  net_init(void);\nvoid net_cleanup(void);\nconst char* net_error(void);\nvoid net_free(void *ptr);\n","c","",[21,45,46,54,60,66],{"__ignoreMap":43},[47,48,51],"span",{"class":49,"line":50},"line",1,[47,52,53],{},"int  net_init(void);\n",[47,55,57],{"class":49,"line":56},2,[47,58,59],{},"void net_cleanup(void);\n",[47,61,63],{"class":49,"line":62},3,[47,64,65],{},"const char* net_error(void);\n",[47,67,69],{"class":49,"line":68},4,[47,70,71],{},"void net_free(void *ptr);\n",[17,73,74,75,78,79,82,83,86,87,90,91,94],{},"所有网络操作前必须先调 ",[21,76,77],{},"net_init()","，退出时调 ",[21,80,81],{},"net_cleanup()","。",[21,84,85],{},"net_error()"," 返回最近一次操作的错误描述（仅调试用，值不会 auto-clear）。",[21,88,89],{},"net_free()"," 释放模块内部分配的内存（如 ",[21,92,93],{},"tcp_peer_addr"," 的返回值）。",[38,96,98],{"className":40,"code":97,"language":42,"meta":43,"style":43},"net_init();\n\u002F\u002F ... 网络操作 ...\nnet_cleanup();\n",[21,99,100,105,110],{"__ignoreMap":43},[47,101,102],{"class":49,"line":50},[47,103,104],{},"net_init();\n",[47,106,107],{"class":49,"line":56},[47,108,109],{},"\u002F\u002F ... 网络操作 ...\n",[47,111,112],{"class":49,"line":62},[47,113,114],{},"net_cleanup();\n",[33,116,118],{"id":117},"dns-解析","DNS 解析",[38,120,122],{"className":40,"code":121,"language":42,"meta":43,"style":43},"int dns_lookup(const char *hostname, char *ip, int ip_size);\n",[21,123,124],{"__ignoreMap":43},[47,125,126],{"class":49,"line":50},[47,127,121],{},[17,129,130,131,134,135,138],{},"将域名解析为 IPv4 地址字符串。返回 0 成功，",[21,132,133],{},"ip"," 中存储点分十进制 IP（如 ",[21,136,137],{},"\"202.202.0.100\"","）。",[38,140,142],{"className":40,"code":141,"language":42,"meta":43,"style":43},"char ip[64];\nif (dns_lookup(\"www.xtu.edu.cn\", ip, sizeof(ip)) == 0)\n    printf(\"IP: %s\", ip);  \u002F\u002F 输出: IP: 202.202.0.100\n",[21,143,144,149,154],{"__ignoreMap":43},[47,145,146],{"class":49,"line":50},[47,147,148],{},"char ip[64];\n",[47,150,151],{"class":49,"line":56},[47,152,153],{},"if (dns_lookup(\"www.xtu.edu.cn\", ip, sizeof(ip)) == 0)\n",[47,155,156],{"class":49,"line":62},[47,157,158],{},"    printf(\"IP: %s\", ip);  \u002F\u002F 输出: IP: 202.202.0.100\n",[33,160,162],{"id":161},"tcp","TCP",[38,164,166],{"className":40,"code":165,"language":42,"meta":43,"style":43},"typedef struct tcp_s tcp_t;\n\n\u002F\u002F 客户端连接\ntcp_t* tcp_connect(const char *host, int port);\n\n\u002F\u002F 服务端监听\ntcp_t* tcp_listen(int port);\ntcp_t* tcp_accept(tcp_t *server);\n\n\u002F\u002F 收发\nint  tcp_send(tcp_t *conn, const char *data, int len);\nint  tcp_recv(tcp_t *conn, char *buf, int buf_size);\nint  tcp_recv_timeout(tcp_t *conn, char *buf, int buf_size, int timeout_ms);\n\n\u002F\u002F 工具\nchar* tcp_peer_addr(tcp_t *conn);  \u002F\u002F 需 net_free\nvoid  tcp_close(tcp_t *conn);\n",[21,167,168,173,179,184,189,194,200,206,212,217,223,229,235,241,246,252,258],{"__ignoreMap":43},[47,169,170],{"class":49,"line":50},[47,171,172],{},"typedef struct tcp_s tcp_t;\n",[47,174,175],{"class":49,"line":56},[47,176,178],{"emptyLinePlaceholder":177},true,"\n",[47,180,181],{"class":49,"line":62},[47,182,183],{},"\u002F\u002F 客户端连接\n",[47,185,186],{"class":49,"line":68},[47,187,188],{},"tcp_t* tcp_connect(const char *host, int port);\n",[47,190,192],{"class":49,"line":191},5,[47,193,178],{"emptyLinePlaceholder":177},[47,195,197],{"class":49,"line":196},6,[47,198,199],{},"\u002F\u002F 服务端监听\n",[47,201,203],{"class":49,"line":202},7,[47,204,205],{},"tcp_t* tcp_listen(int port);\n",[47,207,209],{"class":49,"line":208},8,[47,210,211],{},"tcp_t* tcp_accept(tcp_t *server);\n",[47,213,215],{"class":49,"line":214},9,[47,216,178],{"emptyLinePlaceholder":177},[47,218,220],{"class":49,"line":219},10,[47,221,222],{},"\u002F\u002F 收发\n",[47,224,226],{"class":49,"line":225},11,[47,227,228],{},"int  tcp_send(tcp_t *conn, const char *data, int len);\n",[47,230,232],{"class":49,"line":231},12,[47,233,234],{},"int  tcp_recv(tcp_t *conn, char *buf, int buf_size);\n",[47,236,238],{"class":49,"line":237},13,[47,239,240],{},"int  tcp_recv_timeout(tcp_t *conn, char *buf, int buf_size, int timeout_ms);\n",[47,242,244],{"class":49,"line":243},14,[47,245,178],{"emptyLinePlaceholder":177},[47,247,249],{"class":49,"line":248},15,[47,250,251],{},"\u002F\u002F 工具\n",[47,253,255],{"class":49,"line":254},16,[47,256,257],{},"char* tcp_peer_addr(tcp_t *conn);  \u002F\u002F 需 net_free\n",[47,259,261],{"class":49,"line":260},17,[47,262,263],{},"void  tcp_close(tcp_t *conn);\n",[17,265,266,269,270,273,274,277,278,280,281,82],{},[21,267,268],{},"tcp_recv_timeout"," 的 ",[21,271,272],{},"timeout_ms"," 传 ",[21,275,276],{},"-1"," 表示无限等待。",[21,279,93],{}," 返回格式 ",[21,282,283],{},"\"ip:port\"",[38,285,287],{"className":40,"code":286,"language":42,"meta":43,"style":43},"\u002F\u002F 时间服务器查询示例\ntcp_t *conn = tcp_connect(\"time.nist.gov\", 13);\nif (conn) {\n    char buf[1024] = {0};\n    int n = tcp_recv_timeout(conn, buf, sizeof(buf)-1, 5000);\n    if (n > 0) printf(\"时间: %s\", buf);\n    tcp_close(conn);\n}\n",[21,288,289,294,299,304,309,314,319,324],{"__ignoreMap":43},[47,290,291],{"class":49,"line":50},[47,292,293],{},"\u002F\u002F 时间服务器查询示例\n",[47,295,296],{"class":49,"line":56},[47,297,298],{},"tcp_t *conn = tcp_connect(\"time.nist.gov\", 13);\n",[47,300,301],{"class":49,"line":62},[47,302,303],{},"if (conn) {\n",[47,305,306],{"class":49,"line":68},[47,307,308],{},"    char buf[1024] = {0};\n",[47,310,311],{"class":49,"line":191},[47,312,313],{},"    int n = tcp_recv_timeout(conn, buf, sizeof(buf)-1, 5000);\n",[47,315,316],{"class":49,"line":196},[47,317,318],{},"    if (n > 0) printf(\"时间: %s\", buf);\n",[47,320,321],{"class":49,"line":202},[47,322,323],{},"    tcp_close(conn);\n",[47,325,326],{"class":49,"line":208},[47,327,328],{},"}\n",[33,330,332],{"id":331},"udp","UDP",[38,334,336],{"className":40,"code":335,"language":42,"meta":43,"style":43},"typedef struct udp_s udp_t;\n\nudp_t* udp_create(int port);          \u002F\u002F port=0 自动分配\nint  udp_send(udp_t *sock, const char *host, int port,\n                     const char *data, int len);\nint  udp_recv(udp_t *sock, char *buf, int buf_size,\n                     char *src_ip, int *src_port, int timeout_ms);\nvoid udp_close(udp_t *sock);\n",[21,337,338,343,347,352,357,362,367,372],{"__ignoreMap":43},[47,339,340],{"class":49,"line":50},[47,341,342],{},"typedef struct udp_s udp_t;\n",[47,344,345],{"class":49,"line":56},[47,346,178],{"emptyLinePlaceholder":177},[47,348,349],{"class":49,"line":62},[47,350,351],{},"udp_t* udp_create(int port);          \u002F\u002F port=0 自动分配\n",[47,353,354],{"class":49,"line":68},[47,355,356],{},"int  udp_send(udp_t *sock, const char *host, int port,\n",[47,358,359],{"class":49,"line":191},[47,360,361],{},"                     const char *data, int len);\n",[47,363,364],{"class":49,"line":196},[47,365,366],{},"int  udp_recv(udp_t *sock, char *buf, int buf_size,\n",[47,368,369],{"class":49,"line":202},[47,370,371],{},"                     char *src_ip, int *src_port, int timeout_ms);\n",[47,373,374],{"class":49,"line":208},[47,375,376],{},"void udp_close(udp_t *sock);\n",[17,378,379,382,383,269,386,389,390,393],{},[21,380,381],{},"udp_create(0)"," 创建绑定到随机端口的 UDP 套接字。",[21,384,385],{},"udp_recv",[21,387,388],{},"src_ip"," 和 ",[21,391,392],{},"src_port"," 可传 NULL 跳过读取。",[33,395,397],{"id":396},"http","HTTP",[38,399,401],{"className":40,"code":400,"language":42,"meta":43,"style":43},"typedef struct http_s http_t;\n\nhttp_t* http_get(const char *url);\nhttp_t* http_post(const char *url, const char *body,\n                                 const char *content_type,\n                                 const char *auth_header);\nint  http_status(http_t *resp);\nconst char* http_body(http_t *resp);\nint  http_body_len(http_t *resp);\nvoid http_free(http_t *resp);\n",[21,402,403,408,412,417,422,427,432,437,442,447],{"__ignoreMap":43},[47,404,405],{"class":49,"line":50},[47,406,407],{},"typedef struct http_s http_t;\n",[47,409,410],{"class":49,"line":56},[47,411,178],{"emptyLinePlaceholder":177},[47,413,414],{"class":49,"line":62},[47,415,416],{},"http_t* http_get(const char *url);\n",[47,418,419],{"class":49,"line":68},[47,420,421],{},"http_t* http_post(const char *url, const char *body,\n",[47,423,424],{"class":49,"line":191},[47,425,426],{},"                                 const char *content_type,\n",[47,428,429],{"class":49,"line":196},[47,430,431],{},"                                 const char *auth_header);\n",[47,433,434],{"class":49,"line":202},[47,435,436],{},"int  http_status(http_t *resp);\n",[47,438,439],{"class":49,"line":208},[47,440,441],{},"const char* http_body(http_t *resp);\n",[47,443,444],{"class":49,"line":214},[47,445,446],{},"int  http_body_len(http_t *resp);\n",[47,448,449],{"class":49,"line":219},[47,450,451],{},"void http_free(http_t *resp);\n",[17,453,454,455,389,458,461],{},"支持 HTTPS（通过 WinHTTP）。",[21,456,457],{},"content_type",[21,459,460],{},"auth_header"," 可传 NULL 跳过。",[38,463,465],{"className":40,"code":464,"language":42,"meta":43,"style":43},"\u002F\u002F 获取公网 IP\nhttp_t *resp = http_get(\"https:\u002F\u002Fhttpbin.org\u002Fip\");\nif (resp) {\n    printf(\"HTTP %d: %s\", http_status(resp), http_body(resp));\n    http_free(resp);\n}\n",[21,466,467,472,477,482,487,492],{"__ignoreMap":43},[47,468,469],{"class":49,"line":50},[47,470,471],{},"\u002F\u002F 获取公网 IP\n",[47,473,474],{"class":49,"line":56},[47,475,476],{},"http_t *resp = http_get(\"https:\u002F\u002Fhttpbin.org\u002Fip\");\n",[47,478,479],{"class":49,"line":62},[47,480,481],{},"if (resp) {\n",[47,483,484],{"class":49,"line":68},[47,485,486],{},"    printf(\"HTTP %d: %s\", http_status(resp), http_body(resp));\n",[47,488,489],{"class":49,"line":191},[47,490,491],{},"    http_free(resp);\n",[47,493,494],{"class":49,"line":196},[47,495,328],{},[33,497,499],{"id":498},"url-编码","URL 编码",[38,501,503],{"className":40,"code":502,"language":42,"meta":43,"style":43},"char* url_encode(const char *str);  \u002F\u002F 需 net_free\n",[21,504,505],{"__ignoreMap":43},[47,506,507],{"class":49,"line":50},[47,508,502],{},[17,510,511],{},"对字符串进行 URL 百分号编码。适用于构造自定义 HTTP 查询参数。",[33,513,515],{"id":514},"websocket-hub","WebSocket Hub",[17,517,518],{},"基于原生 Winsock WebSocket 协议（RFC 6455）实现的轻量级 pub\u002Fsub 消息枢纽。单线程、无锁、非阻塞轮询。",[520,521,522],"h3",{"id":522},"设计思路",[524,525,526,530,533,536],"ul",{},[527,528,529],"li",{},"服务端监听端口，接受 WS 客户端连接",[527,531,532],{},"客户端通过 JSON 指令订阅\u002F取消订阅话题",[527,534,535],{},"消息通过话题路由，发送者不会收到自己的消息",[527,537,538],{},"所有客户端对等，不分角色",[520,540,542],{"id":541},"创建-关闭","创建 \u002F 关闭",[38,544,546],{"className":40,"code":545,"language":42,"meta":43,"style":43},"typedef struct ws_hub_s ws_hub_t;\n\nws_hub_t*  ws_hub_create(int port);\nvoid       ws_hub_close(ws_hub_t *hub);\n",[21,547,548,553,557,562],{"__ignoreMap":43},[47,549,550],{"class":49,"line":50},[47,551,552],{},"typedef struct ws_hub_s ws_hub_t;\n",[47,554,555],{"class":49,"line":56},[47,556,178],{"emptyLinePlaceholder":177},[47,558,559],{"class":49,"line":62},[47,560,561],{},"ws_hub_t*  ws_hub_create(int port);\n",[47,563,564],{"class":49,"line":68},[47,565,566],{},"void       ws_hub_close(ws_hub_t *hub);\n",[17,568,569,572,573,138],{},[21,570,571],{},"ws_hub_create"," 在指定端口启动 WS 服务器（",[21,574,575],{},"ws:\u002F\u002F",[520,577,578],{"id":578},"连接管理",[38,580,582],{"className":40,"code":581,"language":42,"meta":43,"style":43},"int  ws_hub_accept(ws_hub_t *hub, int timeout_ms);\nint  ws_hub_count(ws_hub_t *hub);\nint  ws_hub_conn_id(ws_hub_t *hub, int index);\nvoid ws_hub_disconnect(ws_hub_t *hub, int conn_id);\n",[21,583,584,589,594,599],{"__ignoreMap":43},[47,585,586],{"class":49,"line":50},[47,587,588],{},"int  ws_hub_accept(ws_hub_t *hub, int timeout_ms);\n",[47,590,591],{"class":49,"line":56},[47,592,593],{},"int  ws_hub_count(ws_hub_t *hub);\n",[47,595,596],{"class":49,"line":62},[47,597,598],{},"int  ws_hub_conn_id(ws_hub_t *hub, int index);\n",[47,600,601],{"class":49,"line":68},[47,602,603],{},"void ws_hub_disconnect(ws_hub_t *hub, int conn_id);\n",[524,605,606,616,622,630],{},[527,607,608,611,612,615],{},[21,609,610],{},"ws_hub_accept"," — 接受新连接，返回 ",[21,613,614],{},"conn_id","（-1=超时\u002F错误）",[527,617,618,621],{},[21,619,620],{},"ws_hub_count"," — 当前连接数",[527,623,624,627,628],{},[21,625,626],{},"ws_hub_conn_id"," — 按索引获取 ",[21,629,614],{},[527,631,632,635],{},[21,633,634],{},"ws_hub_disconnect"," — 断开指定连接",[520,637,639],{"id":638},"订阅-发布","订阅 \u002F 发布",[38,641,643],{"className":40,"code":642,"language":42,"meta":43,"style":43},"int  ws_hub_subscribe(ws_hub_t *hub, int conn_id, const char *topic);\nint  ws_hub_unsubscribe(ws_hub_t *hub, int conn_id, const char *topic);\nint  ws_hub_publish(ws_hub_t *hub, int sender_id, const char *topic,\n                    const char *data, int len);\nint  ws_hub_recv(ws_hub_t *hub, int conn_id,\n                 char *buf, int buf_size, int timeout_ms);\nint  ws_hub_poll(ws_hub_t *hub, int timeout_ms);\n",[21,644,645,650,655,660,665,670,675],{"__ignoreMap":43},[47,646,647],{"class":49,"line":50},[47,648,649],{},"int  ws_hub_subscribe(ws_hub_t *hub, int conn_id, const char *topic);\n",[47,651,652],{"class":49,"line":56},[47,653,654],{},"int  ws_hub_unsubscribe(ws_hub_t *hub, int conn_id, const char *topic);\n",[47,656,657],{"class":49,"line":62},[47,658,659],{},"int  ws_hub_publish(ws_hub_t *hub, int sender_id, const char *topic,\n",[47,661,662],{"class":49,"line":68},[47,663,664],{},"                    const char *data, int len);\n",[47,666,667],{"class":49,"line":191},[47,668,669],{},"int  ws_hub_recv(ws_hub_t *hub, int conn_id,\n",[47,671,672],{"class":49,"line":196},[47,673,674],{},"                 char *buf, int buf_size, int timeout_ms);\n",[47,676,677],{"class":49,"line":202},[47,678,679],{},"int  ws_hub_poll(ws_hub_t *hub, int timeout_ms);\n",[524,681,682,688,694,700,706],{},[527,683,684,687],{},[21,685,686],{},"ws_hub_subscribe"," — 订阅话题（一个连接可订阅多个）",[527,689,690,693],{},[21,691,692],{},"ws_hub_unsubscribe"," — 取消订阅",[527,695,696,699],{},[21,697,698],{},"ws_hub_publish"," — 向某话题所有订阅者（排除发送者）推送消息",[527,701,702,705],{},[21,703,704],{},"ws_hub_recv"," — 接收指定连接的一条消息",[527,707,708,711,712,714],{},[21,709,710],{},"ws_hub_poll"," — 轮询所有连接，返回有消息待读的 ",[21,713,614],{},"（-1=无）",[520,716,717],{"id":717},"限制",[719,720,721,734],"table",{},[722,723,724],"thead",{},[725,726,727,731],"tr",{},[728,729,730],"th",{},"项",[728,732,733],{},"上限",[735,736,737,746,754,762],"tbody",{},[725,738,739,743],{},[740,741,742],"td",{},"最大连接数",[740,744,745],{},"64",[725,747,748,751],{},[740,749,750],{},"话题名长度",[740,752,753],{},"64 字符",[725,755,756,759],{},[740,757,758],{},"每连接可订阅话题数",[740,760,761],{},"16",[725,763,764,767],{},[740,765,766],{},"单条消息最大长度",[740,768,769],{},"16 KB",[520,771,772],{"id":772},"示例",[38,774,776],{"className":40,"code":775,"language":42,"meta":43,"style":43},"ws_hub_t *hub = ws_hub_create(9099);\nif (!hub) { \u002F* 错误处理 *\u002F }\n\nwhile (g_running) {\n    \u002F* 接受新连接 *\u002F\n    int cid = ws_hub_accept(hub, 200);\n    if (cid >= 0) {\n        ws_hub_subscribe(hub, cid, \"agent\");\n        ws_hub_subscribe(hub, cid, \"js\");\n    }\n\n    \u002F* 轮询消息 *\u002F\n    int ready = ws_hub_poll(hub, 200);\n    if (ready \u003C 0) continue;\n\n    char buf[16384];\n    int len = ws_hub_recv(hub, ready, buf, sizeof(buf) - 1, 0);\n    if (len \u003C= 0) { ws_hub_disconnect(hub, ready); continue; }\n    buf[len] = '\\0';\n\n    \u002F* 解析 JSON，按 topic 发布 *\u002F\n    \u002F\u002F ws_hub_publish(hub, ready, topic, buf, len);\n}\n\nws_hub_close(hub);\n",[21,777,778,783,788,792,797,802,807,812,817,822,827,831,836,841,846,850,855,860,866,872,877,883,889,894,899],{"__ignoreMap":43},[47,779,780],{"class":49,"line":50},[47,781,782],{},"ws_hub_t *hub = ws_hub_create(9099);\n",[47,784,785],{"class":49,"line":56},[47,786,787],{},"if (!hub) { \u002F* 错误处理 *\u002F }\n",[47,789,790],{"class":49,"line":62},[47,791,178],{"emptyLinePlaceholder":177},[47,793,794],{"class":49,"line":68},[47,795,796],{},"while (g_running) {\n",[47,798,799],{"class":49,"line":191},[47,800,801],{},"    \u002F* 接受新连接 *\u002F\n",[47,803,804],{"class":49,"line":196},[47,805,806],{},"    int cid = ws_hub_accept(hub, 200);\n",[47,808,809],{"class":49,"line":202},[47,810,811],{},"    if (cid >= 0) {\n",[47,813,814],{"class":49,"line":208},[47,815,816],{},"        ws_hub_subscribe(hub, cid, \"agent\");\n",[47,818,819],{"class":49,"line":214},[47,820,821],{},"        ws_hub_subscribe(hub, cid, \"js\");\n",[47,823,824],{"class":49,"line":219},[47,825,826],{},"    }\n",[47,828,829],{"class":49,"line":225},[47,830,178],{"emptyLinePlaceholder":177},[47,832,833],{"class":49,"line":231},[47,834,835],{},"    \u002F* 轮询消息 *\u002F\n",[47,837,838],{"class":49,"line":237},[47,839,840],{},"    int ready = ws_hub_poll(hub, 200);\n",[47,842,843],{"class":49,"line":243},[47,844,845],{},"    if (ready \u003C 0) continue;\n",[47,847,848],{"class":49,"line":248},[47,849,178],{"emptyLinePlaceholder":177},[47,851,852],{"class":49,"line":254},[47,853,854],{},"    char buf[16384];\n",[47,856,857],{"class":49,"line":260},[47,858,859],{},"    int len = ws_hub_recv(hub, ready, buf, sizeof(buf) - 1, 0);\n",[47,861,863],{"class":49,"line":862},18,[47,864,865],{},"    if (len \u003C= 0) { ws_hub_disconnect(hub, ready); continue; }\n",[47,867,869],{"class":49,"line":868},19,[47,870,871],{},"    buf[len] = '\\0';\n",[47,873,875],{"class":49,"line":874},20,[47,876,178],{"emptyLinePlaceholder":177},[47,878,880],{"class":49,"line":879},21,[47,881,882],{},"    \u002F* 解析 JSON，按 topic 发布 *\u002F\n",[47,884,886],{"class":49,"line":885},22,[47,887,888],{},"    \u002F\u002F ws_hub_publish(hub, ready, topic, buf, len);\n",[47,890,892],{"class":49,"line":891},23,[47,893,328],{},[47,895,897],{"class":49,"line":896},24,[47,898,178],{"emptyLinePlaceholder":177},[47,900,902],{"class":49,"line":901},25,[47,903,904],{},"ws_hub_close(hub);\n",[33,906,907],{"id":907},"完整示例",[17,909,910,911,914,915,82],{},"参见 ",[21,912,913],{},"samples\u002Fnetwork_info_demo\u002F","、",[21,916,917],{},"samples\u002Fai_browser_demo\u002F",[33,919,920],{"id":920},"编译要求",[17,922,923],{},"链接时需要额外两个库：",[38,925,930],{"className":926,"code":928,"language":929},[927],"language-text","ws2_32.lib winhttp.lib\n","text",[21,931,928],{"__ignoreMap":43},[17,933,934],{},"对应的 build.bat 模板：",[38,936,940],{"className":937,"code":938,"language":939,"meta":43,"style":43},"language-bat shiki shiki-themes github-light github-dark","cl main.c \u002FFe:demo.exe \u002Flink eduwin.lib user32.lib gdi32.lib gdiplus.lib comctl32.lib comdlg32.lib shell32.lib winmm.lib ws2_32.lib winhttp.lib\n","bat",[21,941,942],{"__ignoreMap":43},[47,943,944],{"class":49,"line":50},[47,945,938],{},[947,948,949],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":43,"searchDepth":56,"depth":56,"links":951},[952,953,954,955,956,957,958,966,967],{"id":35,"depth":56,"text":36},{"id":117,"depth":56,"text":118},{"id":161,"depth":56,"text":162},{"id":331,"depth":56,"text":332},{"id":396,"depth":56,"text":397},{"id":498,"depth":56,"text":499},{"id":514,"depth":56,"text":515,"children":959},[960,961,962,963,964,965],{"id":522,"depth":62,"text":522},{"id":541,"depth":62,"text":542},{"id":578,"depth":62,"text":578},{"id":638,"depth":62,"text":639},{"id":717,"depth":62,"text":717},{"id":772,"depth":62,"text":772},{"id":907,"depth":56,"text":907},{"id":920,"depth":56,"text":920},"md",{},"\u002Fdocs\u002Fapi\u002Feduwin-net-api",{"title":5,"description":43},"docs\u002Fapi\u002Feduwin-net-api","tHJg0snz2RY3jy9c6j75m2mlI8Z1Z6EaLuzeyoPMc48",1782488679849]