【问题标题】:How to detect if a port is already in use server side (in C++ on windows)?如何检测端口是否已在服务器端使用(在 Windows 上的 C++ 中)?
【发布时间】:2019-06-05 08:14:26
【问题描述】:

这当然是一个常见问题,但不是在这个术语中(windows、服务器端、接受多连接)。

我的目标是接受在端口上启动服务器列表以进行多个连接,前提是在此之前端口被检测到“未使用”。

在我放置//HERE... 的那一行,bind 并没有像我预期的那样返回SOCKET_ERROR 状态。 也许我做错了什么。

如何检测我的端口没有被其他应用程序使用?

这里是端口运行前的状态(使用中)

netstat -an
  TCP    127.0.0.1:2005         0.0.0.0:0              LISTENING

我希望这个 sn-p 足以解释我在做什么,它是几个步骤的合并。

WSADATA WSAData;
int err = WSAStartup(MAKEWORD(2, 2), &WSAData);

SOCKADDR_IN sin;
socklen_t recsize = sizeof(sin);
int one = 1;

SOCKADDR_IN* csin;
SOCKET csock = INVALID_SOCKET;
socklen_t crecsize = sizeof(SOCKADDR_IN);
int sock_err;

if (m_socket != INVALID_SOCKET)
{
    memset(&sin, 0, recsize);
    if(m_blocal)
        sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);   
    else
        sin.sin_addr.s_addr = htonl(INADDR_ANY);

    sin.sin_family = AF_INET;                       
    sin.sin_port = htons(m_iPort);

    setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(int));
    sock_err = bind(m_socket, (SOCKADDR*)&sin, recsize);
    //HERE I want to be sure no one else runs on this port

    //rest of the code using: select(m_socket + 1, &rd, &wr, &er, &timeout);
}

closesocket(m_socket);
WSACleanup();

【问题讨论】:

  • 也许一个解决方案是一个虚拟客户端,它尝试在本地主机上连接但在确认时取消?

标签: c++ windows sockets networking server


【解决方案1】:

不要设置SO_REUSEADDR。如果地址已被使用,bind() 将失败,WSAGetLastError() 将返回 WSAEADDRINUSE

另外请注意,如果 IP 地址不同,两个进程仍然可以绑定到同一个端口,例如,一个进程绑定到localhost,另一个进程绑定到 LAN 网络地址。

【讨论】:

  • 我认为SO_REUSEADDR 能够在同一个端口上重新监听(例如,用于多个传入连接)。第一次没有任何影响。
  • 使用套接字你bind() 一次,然后你可以accept() 一个或多个连接。 accept() 返回一个用于通信的新套接字。 SO_REUSEADDR 允许不同的进程将bind() 连接到同一个端口,这通常不是您想要或不应该做的。
猜你喜欢
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2021-05-03
  • 2016-12-17
  • 2010-10-06
  • 1970-01-01
相关资源
最近更新 更多