QTcpSocket false连接到QTcpServer

时间:2012-12-18 18:33:49

标签: connection qtcpsocket qtcpserver

因为有一段时间我一直在和Qt一起工作(对不起我的英语)。我现在正在使用QtNetwork。

我需要创建一个像客户端一样的系统服务器。基本的想法是这些:

  • 两者(客户端和服务器)的IP都可以更改。无法将服务器IP存储在客户端上的配置文件中。因此,服务器必须以某种方式公开它的IP,并且客户端必须能够检测要连接的服务器IP。

  • 客户端必须能够在没有服务器的情况下工作,并更新服务器(连接后)的工作。

  • 客户端和服务器在同一个WLAN网络中运行,因此无需通过互联网连接。

  • 这个新系统旨在取代旧系统(也就是客户端和服务器)。旧服务器仅使用UDP广播消息与客户端通信,因此,消息会丢失一些消息。

所以,第一点,我在服务器中实现了一个计时器。此计时器每隔X次通过UDP发送一条广播消息,并显示消息“连接到服务器”。此消息的想法是客户端检测到此类消息并获取服务器IP以进行连接。

服务器使用QTcpServer来检测客户端连接,并且每个客户端存储一个新的QTcpSocket进行通信。

客户端在获得服务器IP后使用TcpSocket进行连接。

听起来很简单。

我已经实现了连接系统,并且在本地计算机(服务器和在同一台计算机上运行的一些客户端)上,系统可以正常运行。可以完成连接并进行通信。客户端和服务器都是使用gcc 4.7.2在Chakra Linux 64位上编译的。系统上安装的Qt版本是4.8.4。

现在,我用两台真机测试了系统(运行在Chakra Linux 64位上的服务器和运行在Windows 7上的客户机(大约32位和另外64位)和两台Windows 8(仅32位))。 Windows版本的客户端已在运行Windows 7 32位的虚拟机(VirtualBox 4.2.4)上编译,使用Qt 4.8.3和MingW 4.6.2。 Windows客户端运行所有32位编译版本的客户端(所有32位Windows计算机和64位Windows计算机)。

客户端可以检测并读取广播消息(UDP,在端口45454上工作),一旦获得服务器IP(检测到IP正确),就会尝试连接。

问题是,从7个客户端,只有一个Windows 8已连接一次。所有客户端都尝试连接,所有客户端的QTcpSocket都发出“已连接”信号,但服务器没有检测到任何连接。

这是完全随机的,因为有时我可以连接1或2个客户端。其他时间没有。

此代码用于客户端广播初始化。

broadcast_socket = new QUdpSocket ();
server_connection = new QTcpSocket ();
if ( broadcast_socket->bind ( QHostAddress::Any , cfg->networkControl ()->udpPort () ) == false )
{
   cout << ">> NetworkManager: Error setting port " << cfg->networkControl ()->udpPort () << " for UDP broadcast listen." << endl;
}
connect ( broadcast_socket , SIGNAL ( readyRead () ) , this , SLOT ( broadcastMessageReceived () ) );
connect ( server_connection , SIGNAL ( readyRead () ) , this , SLOT ( serverMessageReceived () ) );
connect ( server_connection , SIGNAL ( disconnected () ) , this , SLOT ( serverConnectionLost () ) );
connect ( server_connection , SIGNAL ( connected () ) , this , SLOT ( serverConnected () ) );

此代码来自客户端,当收到服务器广播消息时。

void NetworkManager::broadcastMessageReceived ( void )
{
   while ( broadcast_socket->hasPendingDatagrams () )
   {
      QByteArray datagram;
      QHostAddress sender_adress;
      datagram.resize ( broadcast_socket->pendingDatagramSize () );
      broadcast_socket->readDatagram ( datagram.data () , datagram.size () , &sender_adress );
      server_ip = sender_adress;

      QString message ( datagram.data () );

      cout << ">> NetworkManager: Broadcast message received: " << message.toStdString () << endl;      
      if ( message == QString ( "0:%1" ).arg ( NetworkMessages::ConnectToServer ) )
      {         
         if ( connection_status == 0 ) // If 0, there is no connection still.
         {
            cout << endl << "   Server asking for connection." << endl;
            cout << "   Server IP: " << sender_adress.toString ().toStdString () << endl;
            cout << "   Trying to connect." << endl;
            server_connection->connectToHost ( sender_adress , cfg->networkControl ()->tcpPort () );        
            cout << "   Waiting for responce." << endl;        
            connection_status = 1;
            break;
         }
      }
   } 
   return;
}

在服务器端,我有这个代码来初始化:

connection_server = new QTcpServer ();
connect ( connection_server , SIGNAL ( newConnection () ) , this , SLOT ( connectClient () ) );

if ( connection_server->listen ( QHostAddress::Any , cfg->networkControl ()->tcpPort () ) == false )
{
   cout << ">> NetworkManager: Error setting port " << cfg->networkControl ()->tcpPort () << " for TCP server use" << endl;
}

这是连接新客户端的代码的一部分:

void NetworkManager::connectClient ( void )
{
   cout << ">> NetworkManager: New client request." << endl;
   QTcpSocket* new_client = connection_server->nextPendingConnection ();
   connection_sockets[ i ] = new_client; // This is a QList of QTcpSocket pointers, the value of 'i' is calculated previously
   connect ( new_client , SIGNAL ( readyRead () ) , connection_listeners[ i ] , SLOT ( readyRead () ) );
   connect ( new_client , SIGNAL ( disconnected () ) , connection_listeners[ i ] , SLOT ( disconnected () ) );
   connection_state[ i ] = 1;

   cout << "   Asking to client with IP " << new_client->peerAddress ().toString ().toStdString () << " identify." << endl;
   connection_state[ i ] = 1;

   sendToClient ( QObject::tr ( "0:%1" ).arg ( NetworkMessages::IdentifyYourself ) , i );
}

“sendToClient”成员函数只在连接后才向客户端发送消息。

所以,问题在于,我不知道为什么会有这样的随机连接,大部分时间都是错误连接(客户端再次发出连接信号,但在服务器端没有信号发出)当客户连接...)。

我不知道我做错了什么......

客户端和服务器都使用UDP端口45454和TCP端口8888.我已经更改了TCP端口值(在客户端,服务器和两者上)和相同的故事。我已经更改了TCP por,如果两者都没有相同的端口,则消息不会到达客户端......

对于长文本感到抱歉,但我认为最好告诉你我做了什么......

我正在寻找可能是我的问题的建议,或者如果我的代码有问题...但请记住,有时(有时候)一两个客户可以真正连接......

1 个答案:

答案 0 :(得分:0)

connection_status = 1;

void NetworkManager::broadcastMessageReceived ( void )不应该在那里。连接成功后,应在serverConnected ()中设置。