【发布时间】:2012-05-04 21:20:34
【问题描述】:
操作系统是 Linux。 我有一个可以实时更改其端口的服务器进程。不过我想提前知道绑定前端口是否空闲。
场景:服务器绑定 localhost:5000 并在 localhost:6000 接收到绑定请求。服务器必须检查端口是否空闲。此问题寻求提供检查端口是否空闲的例程的答案。
为了记录,我正在使用代码 sn-p 编辑我的问题,该代码检查端口是否可以免费使用。这并不意味着它会被使用。下面的代码回答了“如果端口现在可用”的问题,它不使用它。打开一个套接字,检查 bind 是否返回 EADDRINUSE 并关闭套接字。
#include <iostream>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
int main(int argc, char **argv) {
struct sockaddr_in serv_addr;
if( argc < 2 )
return 0;
int port = atoi(argv[1]);
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if( sockfd < 0 ) {
printf("socket error\n");
return 0;
} else {
printf("Opened fd %d\n", sockfd);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
if( errno == EADDRINUSE )
{
printf("the port is not available. already to other process\n");
} else {
printf("could not bind to process (%d) %s\n", errno, strerror(errno));
}
}
if (close (sockfd) < 0 ) {
printf("did not close fd: %s\n", strerror(errno));
return errno;
}
return 0;
}
这是一些示例运行(部分输出)
[bash{1051}{51}]:[~/some_sources/checkbind]::./a.out 41067
the port is not available. already to other process
[bash{1052}{52}]:[~/some_sources/checkbind]::./a.out 22
could not bind to process (13) Permission denied
[bash{1053}{53}]:[~/some_sources/checkbind]::./a.out 22000
Opened fd 3
【问题讨论】:
-
尝试绑定它,如果失败,它不是免费的...
-
Nicks 建议可能是最便携的解决方案,但也可能有特定于操作系统的方法来做到这一点。您将使用什么操作系统?
-
@Nick 看起来如果端口不是空闲的,则 bind 返回 EADDRINUSE (errno)。
-
即使您设法验证该端口是空闲的,也不能保证在您实际尝试绑定它时它是空闲的。
-
相关:unix.stackexchange.com/a/15513/31228,建议保留一系列端口的策略。
标签: c linux sockets network-programming