我使用的QTcpServer应该单独侦听端口。语言是带有Qt 5.9的c ++。该应用程序必须使用MingW在Win和Linux下运行。 QTcpServer的listen方法将标准参数用于套接字选项。对于Win10,Linux将这些选项默认设置为监听端口的单次使用,因此监听工作正常。不幸的是,Win7提供了共享用法,我必须避免这种用法。 我发现QAbstractSocket类让我使用BindFlag :: DontShareAddress创建了一个套接字。我可以将socketdescriptor转发到QTcpServer。然后方法侦听失败(不侦听),方法是声明:在侦听时调用了QTcpServer :: listen()。我使用netstat检查端口状态。 我的代码示例如下:
bool TcpServer::init(QString ipAddress, quint16 port, Command::RoutingProperty clientSocketKind, QString interfaceName)
{
if (mServerIsInit == true) // only 1 server instance
{
return false;
mServer = new (std::nothrow) QTcpServer();
if (mServer == nullptr)
{
return false;
}
mClientSocketKind = clientSocketKind;
mInterfaceName = interfaceName;
// tries to set socket properties to a non sharing port
QTcpSocket tsocket;
if (!tsocket.bind(QHostAddress(ipAddress), port, QAbstractSocket::BindFlag::DontShareAddress))
{
qDebug() << "Socket bind fails";
}
else
{
qDebug() << "Socket bind success";
}
sd = tsocket.socketDescriptor(); // valid socket descriptor
if (!mServer->setSocketDescriptor(sd))
{
qDebug() << "SocketDescriptor fails";
}
sd = mServer->socketDescriptor();
qDebug() << "Socketdescriptor Server " << sd;
//end tries to set socket properties to a non sharing port
if (mServer->listen(QHostAddress(ipAddress), port)) // fails with message ... is always listening
// if (mServer->mServer->isListening()) // is not listening tells netstat
{
qDebug() << "Server status for listening ok: " << mServer->isListening();
qDebug() << "Server listen on " << mServer->serverAddress() << ":" << mServer->serverPort();
connect(mServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
connect(mServer, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(socketErr(QAbstractSocket::SocketError)));
mServerIsInit = true;
return true;
}
else
{
qDebug() << "Server status for listening fail" << mServer->isListening();
delete mServer;
mServer = nullptr;
return false;
}
}
感谢任何想法如何设置套接字选项以专用于侦听端口。
马丁
答案 0 :(得分:0)
根据评论,您可能需要在调用listen
之前在套接字描述符上显式调用QTcpServer::setSocketDescriptor
。
以下代码未经测试,但应该可以使您有所了解...
if (!tsocket.bind(QHostAddress(ipAddress), port, QAbstractSocket::BindFlag::DontShareAddress))
{
qDebug() << "Socket bind fails";
}
else
{
qDebug() << "Socket bind success";
}
sd = tsocket.socketDescriptor(); // valid socket descriptor
/*
* Now make an explicit call to `listen' so that the socket descriptor
* can be passed to QTcpSocket::setSocketDescriptoy.
*/
if (listen(sd, SOMAXCONN) == SOCKET_ERROR)
{
printf("Listen failed with error: %ld\n", WSAGetLastError());
closesocket(sd);
WSACleanup();
/*
* Handle error.
*/
}
if (!mServer->setSocketDescriptor(sd))
{
qDebug() << "SocketDescriptor fails";
}
顺便说一句,请注意,您需要更加谨慎地处理错误-只需致电qDebug
,然后继续操作就会在某个时候再次咬住您。