使用bash确定tcp端口是否绑定(不监听)

时间:2015-04-02 10:55:24

标签: linux bash sockets tcp

我正在尝试确定最近启动的进程绑定的TCP端口是否实际上正由该特定进程使用。

参加 program.cpp

int daemonport = 11234;

struct sockaddr_in loopback;
memset ((char*) &loopback, 0, sizeof (loopback));
socklen_t len = sizeof (loopback);
loopback.sin_family = AF_INET;
loopback.sin_port = htons (daemonport);
loopback.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
daemonfd = socket (AF_INET, SOCK_STREAM, 0);
if (daemonfd < 0)
{
    errx (EXIT_FAILURE, "Critical error");
}
if (bind (daemonfd, (struct sockaddr*) &loopback, sizeof (loopback)) != 0)
{
    errx (EXIT_FAILURE, "Daemon already running, TCP port: '%d'", daemonport);
}
if (getsockname (daemonfd, (struct sockaddr*) &loopback, &len) != 0)
{
    errx (EXIT_FAILURE, "Critical error");
}
printf ("%d\n", ntohs (loopback.sin_port));

if (daemon (1, 0) < 0)
{
    close (daemonfd);
    errx (EXIT_FAILURE, "Failed to daemonize!");
}

// event loop...

close (daemonfd);

现在将tcp套接字绑定(但不监听)到端口11234,我想检查端口是否使用bash脚本绑定进程。

我尝试了各种netstat和lsof模式没有成功:

netstat -a | grep ':11234'以及lsof -i :11234

他们都不打印带有绑定端口的线路。

但是当我第二次尝试运行该程序时,它出错:

Daemon already running, TCP port: '11234'

2 个答案:

答案 0 :(得分:1)

假设Linux,从这开始:

netstat --inet -n -a -p | grep ':myport'

看看你得到了什么。 --inet不再显示IP6和Unix域套接字。 -n显示数字结果,而不是从端口号转换的名称。 -p告诉您哪个进程正在侦听它。

如果这些行中的任何一行处于“LISTEN”状态,那么该端口上的进程就会变得明显。但是,使用该端口的任何打开的连接(甚至“TIME_WAIT”)将阻止重新打开端口,除非您每次绑定它时都使用SO_REUSEPORT option

如果该命令没有向您显示任何内容,则该端口上没有任何内容正在侦听,这意味着您的程序一定存在问题。

您正在打印错误消息,但假设问题已在运行。打印出errno值(使用perror(...)),这样就可以确定问题所在。

答案 1 :(得分:0)

举例来说,要检查端口 56789 是否在本地可用:

port=56789
retval=$(python3 -c 'import socket; s=socket.socket(); s.bind(("", '"${port}"')); print(s.getsockname()[1]); s.close()' 2>/dev/null)
echo "$retval"

如果端口已经绑定,这将打印一个空行,如果没有绑定,将打印 56789。如果端口 56789 最近被使用并关闭,但 TIME_WAIT 时间段尚未过去(通常为一两分钟),则该端口将不可用且上述代码不会回显 56789。

我意识到这有点作弊,因为它也使用 python,但如果 python 3 可用,它是 bash 脚本化的。不需要 sudo。