
libcurl TELNET 協商選項配置指南CURLOPT_TELNETOPTIONS 完整解析【免費下載鏈接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features項目地址: https://gitcode.com/GitHub_Trending/cu/curl本文圍繞 curl 開源倉庫中 TELNET 協議實現的核心接口CURLOPT_TELNETOPTIONS講解如何在 libcurl 中通過curl_slist向 Telnet 服務器傳遞協商選項終端類型、顯示位置、環境變量等并結合 lib/telnet.c 與 lib/setopt.c 的源碼揭示選項解析、協商狀態機與底層發送邏輯。讀完本文你將掌握該接口的完整用法、全部支持選項及其取值范圍并能寫出可實際運行的 TELNET 客戶端代碼。一、接口速覽CURLOPT_TELNETOPTIONS是 libcurl 提供的、專門用于 TELNET 協議選項協商的 easy 接口選項自 libcurl 7.7 版本加入僅在 URL 協議為telnet://時生效。屬性值選項名CURLOPT_TELNETOPTIONS適用協議TELNET引入版本7.7參數類型struct curl_slist *默認值NULL頭文件include/curl/curl.h函數原型#include curl/curl.h CURLcode curl_easy_setopt(CURL *handle, CURLOPT_TELNETOPTIONS, struct curl_slist *cmds);核心語義官方接口文檔傳入一個curl_slist鏈表鏈表中的每個字符串代表一條傳給 Telnet 協商流程的變量格式必須為optionvalue重復調用本選項時最后一次設置會覆蓋之前的所有設置將參數設為NULL可再次禁用本選項libcurl不會復制該鏈表調用方必須保證鏈表在傳輸完成之前一直存活。二、支持的 Telnet 選項接口文檔明確聲明 libcurl 支持TTYPE、XDISPLOC與NEW_ENV三個選項。而深入 lib/telnet.c 的解析邏輯可以發現實際實現還額外支持WS窗口大小與BINARY二進制傳輸開關兩個選項它們在同一個循環中被解析。選項解析實現以下代碼位于 lib/telnet.c是CURLOPT_TELNETOPTIONS的核心解析入口函數telnet_easy_initfor(head >#define CURL_TELOPT_BINARY 0 /* binary 8-bit data */ #define CURL_TELOPT_ECHO 1 /* echo */ #define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */ #define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */ #define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */ #define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */ #define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */ #define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */各選項深入說明TTYPE終端類型設置后將tn-subopt_ttype指向對應值并把us_preferred[CURL_TELOPT_TTYPE]置為CURL_YES表示本端希望在協商通過后以IAC SB TTYPE IS 值 IAC SE格式發送終端類型子選項。若值中包含 IAC 命令字節255會返回CURLE_BAD_FUNCTION_ARGUMENT若值長度超過 1000 字節則返回CURLE_SEND_ERRORlib/telnet.c。XDISPLOC顯示位置處理邏輯與 TTYPE 完全對稱設置tn-subopt_xdisploc并在協商成功后發送IAC SB XDISPLOC IS 值 IAC SElib/telnet.c。NEW_ENV環境變量每條選項以NAME,VALUE格式追加到tn-telnet_vars鏈表同時將us_preferred[CURL_TELOPT_NEW_ENVIRON]置為CURL_YES。協商成功后libcurl 會構造IAC SB NEW_ENVIRON IS ... IAC SE子選項其中變量名以CURL_NEW_ENV_VAR0開頭、變量值以CURL_NEW_ENV_VALUE1作為分隔標記lib/telnet.c。WS窗口大小值必須形如寬x高寬高均為 0655350xffff范圍內的數字。解析使用curlx_str_number與curlx_str_single語法不合法時返回CURLE_SETOPT_OPTION_SYNTAXlib/telnet.c。窗口尺寸最終會以網絡字節序htons寫入IAC SB NAWS w h IAC SE子選項lib/telnet.c。BINARY二進制模式默認情況下 libcurl 會將 BINARY 選項置為CURL_YES與歷史版本行為保持一致見 lib/telnet.c傳入BINARY1保持默認傳入其他值解析為 0則同時關閉本端與對端的二進制協商偏好lib/telnet.c。注意兩個容易踩坑的細節選項值不允許包含 IAC 字節bad_option檢查見 lib/telnet.c源碼注釋明確說明這是為了禁止通過選項值注入命令字節若選項值包含非 ASCII 字符該條會被靜默跳過str_is_nonascii檢查用戶名非 ASCII 時同理返回CURLE_BAD_FUNCTION_ARGUMENT。三、完整可運行示例接口文檔給出了基礎示例CURLOPT_TELNETOPTIONS.md這里將其補全為可直接編譯的完整程序并同時演示 TTYPE、XDISPLOC 與 NEW_ENV 的組合用法#include stdio.h #include curl/curl.h int main(void) { CURL *curl curl_easy_init(); if(curl) { CURLcode result; struct curl_slist *options NULL; /* 終端類型 */ options curl_slist_append(options, TTYPEvt100); /* 環境變量NAME,VALUE 形式逗號分隔 */ options curl_slist_append(options, NEW_ENVUSER,foobar); options curl_slist_append(options, NEW_ENVTERM,vt100); /* X 顯示位置 */ options curl_slist_append(options, XDISPLOC:0.0); /* 窗口大小寬x高 */ options curl_slist_append(options, WS800x600); curl_easy_setopt(curl, CURLOPT_URL, telnet://example.com/); curl_easy_setopt(curl, CURLOPT_TELNETOPTIONS, options); result curl_easy_perform(curl); if(result ! CURLE_OK) fprintf(stderr, curl_easy_perform() failed: %s\n, curl_easy_strerror(result)); curl_easy_cleanup(curl); curl_slist_free_all(options); } return 0; }要點鏈表在curl_easy_perform結束后才釋放滿足 libcurl“不復制鏈表”的生命周期要求選項字符串必須形如KEYvalue缺少會被判定為語法錯誤返回CURLE_SETOPT_OPTION_SYNTAX官方文檔示例中的USERfoobar需要注意USER 變量不需要也不能通過選項列表傳遞。當 URL 中攜帶了user:password憑據如telnet://user:passhost/時libcurl 會在 lib/telnet.c 中自動將用戶名以USER,name形式注入NEW_ENV協商此時手動傳入USER...反而會因“USER”長度4不匹配任何分支而返回CURLE_UNKNOWN_OPTION。四、底層原理選項如何進入協商流程1. 設置階段僅保存指針在 lib/setopt.c 中CURLOPT_TELNETOPTIONS被歸類為 slist 類型選項處理方式非常輕量#ifndef CURL_DISABLE_TELNET case CURLOPT_TELNETOPTIONS: /* * Set a linked list of telnet options */ s-telnet_options slist; break; #endif它只是把指針存進 easy handle 的配置區不拷貝鏈表內容——這正是文檔要求“鏈表必須存活到傳輸結束”的原因。在 lib/setopt.c 的Curl_vsetopt中它與CURLOPT_HTTPHEADER、CURLOPT_QUOTE、CURLOPT_MAIL_RCPT等一樣被統一分派到setopt_slist處理。2. 協商階段RFC 1143 狀態機libcurl 的 TELNET 實現遵循 RFC 1143 的協商規范lib/telnet.c為每個選項維護雙方狀態/* For negotiation compliant to RFC 1143 */ #define CURL_NO 0 #define CURL_YES 1 #define CURL_WANTYES 2 #define CURL_WANTNO 3 #define CURL_EMPTY 0 #define CURL_OPPOSITE 1struct TELNETlib/telnet.c為 256 個可能的選項各維護一組狀態us/usq/us_preferred描述本端we/us意愿him/himq/him_preferred描述對端he/him意愿subnegotiation標記協商通過后需要發送的子選項。CURLOPT_TELNETOPTIONS解析結果寫入us_preferred與subopt_*字段隨后由send_negotiation()lib/telnet.c以IAC WILL/DO/WONT/DONT option三字節命令發起協商。3. 接收階段子選項收集接收側的狀態機lib/telnet.c逐字節掃描輸入流typedef enum { CURL_TS_DATA 0, CURL_TS_IAC, CURL_TS_WILL, CURL_TS_WONT, CURL_TS_DO, CURL_TS_DONT, CURL_TS_CR, CURL_TS_SB, /* sub-option collection */ CURL_TS_SE /* looking for sub-option end */ } TelnetReceive;收到IAC SB后進入子選項收集模式用 512 字節的subbuffer累積數據CURL_SB_ACCUM宏lib/telnet.c收到IAC SE后交給suboption()處理當服務器以DO TTYPE等方式請求時libcurl 將之前配置的 TTYPE/XDISPLOC/NEW_ENV/NAWS 子選項編碼發送回去lib/telnet.c。4. 默認協商偏好即使未調用CURLOPT_TELNETOPTIONSlibcurl 也會默認請求 SGASuppress Go Ahead、BINARY 以及對端 ECHOlib/telnet.c其中 BINARY 可用BINARY選項關閉ECHO 因可能迫使服務器關閉連接而被特殊處理。五、命令行工具映射--telnet-optioncurl 命令行工具通過-t/--telnet-option optionvalue暴露同一能力可多次指定curl -t TTYPEvt100 -t NEW_ENVUSER,foobar -t WS800x600 telnet://example.com/工具側實現位于 src/tool_getparam.c每次調用將參數追加到config-telnet_options鏈表case C_TELNET_OPTION: /* --telnet-option */ /* Telnet options */ err add2list(config-telnet_options, nextarg); break;隨后在 src/config2setopts.c 中一次性映射到 libcurl 接口my_setopt_slist(curl, CURLOPT_TELNETOPTIONS, config-telnet_options);六、返回值與錯誤處理curl_easy_setopt(handle, CURLOPT_TELNETOPTIONS, list)返回CURLcode其中CURLE_OK (0)設置成功CURLE_UNKNOWN_OPTION選項名不匹配長度或拼寫不對如誤寫為TTTYPE或完全不認識該選項CURLE_SETOPT_OPTION_SYNTAX選項缺少或WS的寬/高不是合法數字CURLE_BAD_FUNCTION_ARGUMENT選項值包含 IAC 字節或憑據用戶名含非 ASCII 字符傳輸階段返回CURLE_SEND_ERRORTTYPE/XDISPLOC 值超過 1000 字節等發送階段錯誤傳輸階段返回。注意解析錯誤發生在curl_easy_perform()執行時的 TELNET 協議初始化階段telnet_easy_init而非curl_easy_setopt()調用時因此判斷結果必須結合curl_easy_perform()的返回值與curl_easy_strerror()輸出。七、與其他選項的關系CURLOPT_TELNETOPTIONS與 CURLOPT_QUOTE、CURLOPT_HTTPHEADER 同為 slist 類型接口內存管理約定一致列表不復制、需自行維護生命周期URL 中的user:password憑據會自動注入 NEW_ENV 的USER變量無需也不應通過選項列表重復指定若需在編譯期裁剪 TELNET 支持可在構建時定義CURL_DISABLE_TELNET此時該選項在 lib/setopt.c 中會被整體禁用。八、小結CURLOPT_TELNETOPTIONS是 libcurl 暴露 TELNET 選項協商能力的唯一入口通過curl_slist以optionvalue格式配置 TTYPE、XDISPLOC、NEW_ENV以及實現額外支持的 WS、BINARYlibcurl 會在連接建立后按 RFC 1143 規范自動完成 WILL/DO 協商與子選項收發。掌握本接口需要同時留意三件事鏈表必須存活到傳輸結束、選項名與值格式必須嚴格匹配源碼解析規則、錯誤碼的返回時機在perform階段。配合 lib/telnet.c 與 lib/arpa_telnet.h 閱讀可完整還原從配置到協商的整個 TELNET 數據通路。【免費下載鏈接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features項目地址: https://gitcode.com/GitHub_Trending/cu/curl創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考