我写了一个简单的应用程序,它连接到给定端口上的给定服务器。当端口打开时,一切正常,我收到有关已建立连接的消息。但是,当端口关闭时,没有任何反应,我的程序没有向我显示有关它的信息。
我使用可通过Internet访问的远程服务器测试我的程序。我怎样才能改善这个?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(int argc, char **argv) {
char * ip_addr;
int port;
int sockfd;
struct sockaddr_in server_addr;
if (argc != 3)
{
fprintf(stderr,"Usage: ./canconnect ip port\n");
exit(1);
}
ip_addr = argv[1];
port = atoi(argv[2]);
if (port <= 0)
{
fprintf(stderr,"error: invalid port\n");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
inet_aton(ip_addr, &server_addr.sin_addr);
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
perror("connect");
printf("Port %d is closed on server %s.\n", port, ip_addr);
exit(1);
}
else
{
printf("Connection established. Port %d is open on server %s.\n", port, ip_addr);
}
close(sockfd);
return 0; }
答案 0 :(得分:2)
鉴于该程序在一段时间后实际打印了一些数据,它肯定与 timeout 有关。
为了最终确定主机或端口不可读或由于任何其他原因无法建立连接,connect
会执行多次连接尝试并在一定数量的情况下返回错误时间 - 超时。
超时值可以使用setsockopt
更改为您想要的任何值:
struct timeval timeout;
timeout.tv_sec = 3; // wait for three seconds
timeout.tv_usec = 0;
// set up receive timeout
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
sizeof(timeout)) < 0)
printf("[!] setsockopt failed\n");
答案 1 :(得分:1)
如果远程服务器可以访问,但既不接受也不拒绝连接,则connect()
将阻塞,直到网络连接尝试超时。正如the Linux manual page for connect
(2)所说:
请注意,对于IP套接字,当在服务器上启用syncookies时,超时可能会很长。
实际上,对于端口扫描而言,这是众所周知的防御措施,试图故意引发这种行为。通过使用setsockopt()
设置接收超时,您可能会更快地失败,但是文档在是否适用于connect()
时不一致。