我已经写了一个程序C++,我需要检查TCP端口是否真的为空.
这是功能:
int checkport(char* host, char* port, int timeout)
{
int sock;
struct sockaddr_in sin;
int result = 0;
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(atoi(port));
sin.sin_addr.s_addr = inet_addr(host);
fd_set fdset;
struct timeval tv;
fcntl(sock, F_SETFL, O_NONBLOCK);
int connect_result = connect(sock,(struct sockaddr*)(&sin),sizeof(struct sockaddr_in));
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
tv.tv_sec = timeout;
tv.tv_usec = 0;
int select_result = select(sock + 1, NULL, &fdset, NULL, &tv);
// printf("connect = [%d] | select = [%d]\n",connect_result,select_result);
if(select_result == 1)
{
int so_error;
socklen_t len = sizeof so_error;
getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);
// printf("so_error = [%d] \n",so_error);
if(so_error == 0)
{
//Is connected
if(hitdebug >= 4) puts("CONNECTED");
if(hitdebug >= 2) printf("[%s:%s] OPEN\n",host,port);
result = 1;
}
else
{
if(hitdebug >= 4) puts("CONNECT_ERROR_1");
result = 0;
}
}
else
{
if(hitdebug >= 4) puts("CONNECT_ERROR_2");
result = 0;
}
close(sock);
return result;
}
Run Code Online (Sandbox Code Playgroud)
问题是只检测LISTEN端口,我希望端口100%真实,甚至检测ESTABLISHED,TIME_WAIT等...
输出:
connect = [-1] | select = [1]
so_error = [111]
50983 TEST=[0]
tcp 0 0 1.2.3.4:50983 4.4.4.4:22 ESTABLISHED
connect = [-1] | select = [1]
so_error = [111]
43343 TEST=[0]
tcp 0 0 1.2.3.4:43343 4.4.4.4:22 ESTABLISHED
connect = [-1] | select = [1]
so_error = [0]
64000 TEST=[1]
tcp 0 0 1.2.3.4:64000 0.0.0.0:* LISTEN
tcp 0 0 1.2.3.4:47669 1.2.3.4:64000 TIME_WAIT
connect = [-1] | select = [1]
so_error = [111]
54674 TEST=[0]
connect = [-1] | select = [1]
so_error = [111]
54665 TEST=[0]
Run Code Online (Sandbox Code Playgroud)
对我来说,一个空端口是当我做一个netstat -an | grep 12345 | wc -l,我看到0,甚至不是FIN_WAIT
我怎么能做到这一点?
谢谢.
n. *_* m. 15
if (the_port_is_free(port_number)) {
/* is the port free at this point? */
}
Run Code Online (Sandbox Code Playgroud)
正确的答案是"谁知道?" 当然,它在一个纳秒之前是免费的,当控制在功能的某个地方the_port_is_free,但它现在是免费的吗?还有很多其他的流程,也许其中一个流程在半个纳秒之前就开始了?
这被称为竞争条件.每个程序员都应该理解这个概念.
正是因为这个问题the_port_is_free不是由您的操作系统提供的:它只会给您错误的期望,而不是正确的答案.您无法知道端口现在是否空闲,更重要的是,当您决定绑定它时,它将在一纳秒内自由.绑定端口的唯一方法是继续尝试绑定它.
这种方法适用于一大堆情况.每当有任何类型的共享资源时,通常没有任何函数可以告诉您是否可以获取它.获得它的唯一方法是继续尝试.
| 归档时间: |
|
| 查看次数: |
2605 次 |
| 最近记录: |