【发布时间】: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:感谢您提高我的理解力。