You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LibCurl通过Telnet控制投影仪遇未知选项错误求助

问题:通过libcurl向Telnet投影仪发送查询命令失败

我有一台支持Telnet通信的投影仪,需要发送命令:POWR ?\r查询电源状态。使用PUTTY操作正常,但用以下libcurl代码执行时出错:

FILE* console = fopen("/dev/tty", "w");

CURL* curl = curl_easy_init();
CURLcode res;

if (curl)
{
  CURLcode res;

  struct curl_slist* options;
  options = curl_slist_append(NULL, "TTTYPE=:POWR ?\r");

  curl_easy_setopt(curl, CURLOPT_URL, "telnet://192.168.0.90");
  curl_easy_setopt(curl, CURLOPT_PORT, 1025);
  curl_easy_setopt(curl, CURLOPT_TELNETOPTIONS, options);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
  res = curl_easy_perform(curl);
  if (res != CURLE_OK)
  {
    fprintf(console, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
  }
  curl_easy_cleanup(curl);
  curl_slist_free_all(options);
  fprintf(console, s.c_str());
}

执行后错误信息:

curl_easy_perform() failed: An unknown option was passed in to libcurl

我怀疑问题出在这段代码:

struct curl_slist* options;
options = curl_slist_append(NULL, "TTTYPE=:POWR ?\r");
curl_easy_setopt(curl, CURLOPT_TELNETOPTIONS, options);

请问如何正确发送命令并获取结果?


解决方案

错误原因

你误用了CURLOPT_TELNETOPTIONS——这个选项是用来配置Telnet协议的内置选项(比如终端类型、窗口大小等),格式为OPTION=VALUE,而TTTYPE并不是合法的Telnet选项,直接把查询命令填在这里会导致libcurl识别失败,抛出"未知选项"错误。

正确实现方式

要通过libcurl向Telnet服务器发送自定义命令,需要利用CURLOPT_READFUNCTION回调函数:libcurl在Telnet会话中会主动调用读回调,获取要发送给服务器的数据。具体步骤如下:

  1. 定义读回调函数,返回要发送的查询命令
  2. 通过CURLOPT_READFUNCTION和CURLOPT_READDATA指定回调逻辑
  3. 移除错误的CURLOPT_TELNETOPTIONS配置
  4. 用CURLOPT_WRITEFUNCTION回调接收投影仪返回的数据

修改后的完整代码

#include <curl/curl.h>
#include <string>
#include <cstdio>
#include <cstring>

// 读回调:向投影仪发送查询命令
size_t telnet_read_callback(char* buffer, size_t size, size_t nitems, void* userdata) {
    std::string* cmd = static_cast<std::string*>(userdata);
    if(cmd->empty()) {
        return 0; // 返回0表示无更多数据发送
    }
    size_t copy_len = std::min(size * nitems, cmd->size());
    memcpy(buffer, cmd->data(), copy_len);
    cmd->erase(0, copy_len);
    return copy_len;
}

// 写回调:接收投影仪返回的数据
size_t telnet_write_callback(char* buffer, size_t size, size_t nitems, void* userdata) {
    std::string* response = static_cast<std::string*>(userdata);
    response->append(buffer, size * nitems);
    return size * nitems;
}

int main() {
    FILE* console = fopen("/dev/tty", "w");
    if(!console) {
        perror("fopen failed");
        return 1;
    }

    std::string cmd = ":POWR ?\r"; // 要发送的查询命令
    std::string response; // 存储返回结果

    CURL* curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "telnet://192.168.0.90");
        curl_easy_setopt(curl, CURLOPT_PORT, 1025);
        
        // 设置读回调,发送自定义命令
        curl_easy_setopt(curl, CURLOPT_READFUNCTION, telnet_read_callback);
        curl_easy_setopt(curl, CURLOPT_READDATA, &cmd);
        
        // 设置写回调,接收返回数据
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, telnet_write_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

        // 执行Telnet会话
        CURLcode res = curl_easy_perform(curl);
        if(res != CURLE_OK) {
            fprintf(console, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        } else {
            fprintf(console, "投影仪返回结果:\n%s\n", response.c_str());
        }

        curl_easy_cleanup(curl);
    }

    fclose(console);
    return 0;
}

关键说明

  • 读回调:当libcurl需要向Telnet服务器发送数据时触发,我们在这里返回预定义的查询命令,发送完成后返回0终止发送。
  • 写回调:libcurl接收到投影仪返回的数据时触发,将数据追加到字符串中保存。
  • 移除了错误的CURLOPT_TELNETOPTIONS配置,避免非法选项导致的错误。

测试注意事项

  1. 确认投影仪的Telnet端口确实是1025,与代码中CURLOPT_PORT设置一致。
  2. 命令末尾的\r必须保留,和PUTTY操作时的格式保持一致。
  3. 编译时需链接libcurl库,例如GCC编译命令:g++ -o telnet_projector telnet_projector.cpp -lcurl

内容的提问来源于stack exchange,提问作者Peter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:10:32