#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QNetworkInterface>
#include "IMsgInterface.h"
class Server : public QObject
{
Q_OBJECT
public:
explicit Server(QObject *parent = 0);
~Server();
void init(IMsgInterface * pMsgHandler, int port);
void sendData(QString ip, QString data);
void sendData(QString ip, uchar *rawData);
signals:
private slots:
void newConnectSlot();
void readMessage();
void removeUserFormList();
private:
QTcpServer *m_tcpServer;
QMap<QString, QTcpSocket *> m_mapClient;
IMsgInterface *m_pMsgHandler;
};
不要直接调用QTcpServer的listen,通过系统api创建socket,设置SO_REUSEADDR属性,通过QTcpServer::setSocketDescriptor将该socket设置成QTcpServer需要监听的套接字。代码如下:
SOCKET sockfd = 0;
struct sockaddr_in servAddr;
sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
logError("can't open socket");
return false;
}
int flag = 1;
if (::setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(flag)) != 0) {
logError("can't set SO_REUSEADDR");
return false;
}
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = INADDR_ANY;
servAddr.sin_port = htons(port);
if (::bind(sockfd, (struct sockaddr*)&servAddr, sizeof(sockaddr_in)) != 0) {
logError("can't bind socket");
return false;
}
if (::listen(sockfd, SOMAXCONN) != 0) {
logError("can't listen on port");
return false;
}
setSocketDescriptor(sockfd);