【问题标题】:Use a bound client socket for making curl queries使用绑定的客户端套接字进行 curl 查询
【发布时间】:2018-03-16 06:45:30
【问题描述】:

我正在尝试在 C 中实现一个客户端,希望将其绑定到一个固定端口并在 curl 查询中使用获得的 fd。 我希望这个 fd 不被关闭,而是在进程生命周期之前重复使用它,这样即使连接可能关闭,其他进程也无法使用该端口。

由于端口不应该被任何其他进程使用,我没有使用 CURLOPT_LOCALPORT 选项。

通过 https://curl.haxx.se/libcurl/c/libcurl.html 寻找合适的 curl 选项并找到 CURLOPT_OPENSOCKETFUNCTION 和 CURLOPT_SOCKOPTFUNCTION

但是在服务器端检查客户端端口时,没有使用固定端口进行查询。

以下是我来这里之前尝试过的代码块。

//create socket
clientFd = socket(ipType, SOCK_STREAM, 0);

//bind client socket
struct sockaddr_in clientAddr;
clientAddr.sin_family = ipType;
clientAddr.sin_addr.s_addr = inet_addr(clientIP);
clientAddr.sin_port = clientPort;
bind(clientFd, (struct sockaddr *)&clientAddr, sizeof(clientAddr))

//Using CURLOPT_OPENSOCKETFUNCTION
//Based on understanding, we need to make a connection to the server and return //back the fd
static curl_socket_t curl_opensocket(void *myFD, curlsocktype connType, struct curl_sockaddr *peerAddr) // connect to server using client FD
{
   struct sockaddr_in *addr_in = (struct sockaddr_in *)(&(peerAddr->addr));
   remAddr = malloc(INET_ADDRSTRLEN);
   remPort = (u_short)addr_in->sin_port;
   inet_ntop(AF_INET, &(addr_in->sin_addr), remAddr, INET_ADDRSTRLEN);

   sockfd = *(curl_socket_t *)myFD;

   connect(sockfd, (struct sockaddr *)(&(peerAddr->addr)), sizeof(peerAddr->addr);
   return sockfd;
}

curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, curl_opensocket);
curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &clientFD);

使用上述选项集进行查询,正在选择不同的客户端端口并且 fd 正在关闭

//Using CURLOPT_SOCKOPTFUNCTION
//Based on understanding, this gets called after socket creation and before connect

    static int sockopt_callback(void *clientp, curl_socket_t curlfd, curlsocktype purpose)
    {
        (void)clientp;
        (void)curlfd;
        (void)purpose;

        return CURLSOCKTYPE_IPCXN;
    }
    curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
    curl_easy_setopt(curl, CURLOPT_SOCKOPTDATA, &clientFd);

这里也使用不同的客户端端口进行查询,但 clientFd 没有关闭。

请帮帮我,在 curl 查询中使用绑定的 fd,可以终止连接,但不能终止 fd,并且在后续连接中使用 fd 时选择固定端口。

【问题讨论】:

  • 我不明白你为什么不能使用CURLOPT_LOCALPORT?它应该完全按照您的意愿行事,并将套接字绑定到您请求的端口(如果可用)。
  • 'Connection can be terminate, but not the fd' 用语自相矛盾。
  • 我的意思是说 fd 仍然处于活动状态,但已建立的连接将被拆除,下一个查询将使用新连接,但使用相同的绑定 fd。请让我知道我的理解是正确的
  • @Bharath 一旦任何一方关闭了套接字连接,您就不能重用同一个 fd 来打开新连接(除非您在 Windows 上并使用 ConnectEx()DisconnectEx() 重用 @987654327 @句柄)。在大多数平台上,您必须为每个新连接创建一个新 fd。您只需要将它们绑定到同一个本地端口,这就是 CURLOPT_LOCALPORT 为您所做的。但是,对于您正在尝试的内容,您可能必须在每个 fd 上启用 SO_REUSE_(ADDR|PORT),并且在绑定新 fd 之前不要关闭旧 fd,以避免出现竞争条件。
  • 感谢大家抽出宝贵时间帮助我。 @Remy Lebeau:感谢您提高我的理解力。

标签: c sockets curl


【解决方案1】:

在您的“CURLOPT_SOCKOPTFUNCTION”中,您应该返回 CURL_SOCKOPT_ALREADY_CONNECTED 而不是 CURLSOCKTYPE_IPCXN,因为您的套接字已经连接。

查看此处给出的示例代码 https://curl.se/libcurl/c/CURLOPT_OPENSOCKETFUNCTION.html

【讨论】:

    猜你喜欢
    • 2011-03-16
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-07
    • 2011-04-21
    • 1970-01-01
    相关资源
    最近更新 更多