首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QTcpSocket错误连接到QTcpServer

QTcpSocket错误连接到QTcpServer
EN

Stack Overflow用户
提问于 2012-12-18 18:33:48
回答 1查看 1.1K关注 0票数 1

从一段时间以来,我一直与Qt (对不起,我的英语)。我现在正在使用QtNetwork。

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

  • (客户端和服务器)的IP都可以改变。无法将服务器IP存储在客户端上的配置文件中。因此,服务器必须以某种方式公开它的IP,并且客户端必须能够检测到要连接的服务器IP。
  • 客户端必须能够在没有服务器的情况下工作,并更新其工作的服务器(一旦连接)。
  • 客户端和服务器在同一个WLAN网络中运行,因此不需要通过internet进行连接。
  • 这个新系统的目的是替换和旧系统(同时,客户端和服务器)。旧服务器只使用UDP广播消息与客户端通信,因此,有些消息丢失了。

因此,对于第一点,我已经在服务器上实现了一个计时器。这个计时器,每隔X次,通过UDP发送一条消息“连接到服务器”的广播消息。这个消息的思想是客户端检测到这样的消息并让服务器IP连接起来。

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

客户端一旦获得服务器IP,就使用TcpSocket进行连接。

听起来很简单。

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

现在,我已经用两台真正的机器(在Chakra 64位上运行的服务器和在Windows 7上运行的客户机(大约32位和另一个64位)和两台Windows 8(只有32位))测试了系统。Windows版本的客户端是在运行Windows7.32位的虚拟机(VirtualBox 4.2.4)上编译的,QT4.8.3和MingW 4.6.2。Windows客户端运行客户端的所有32位编译版本(所有32位Windows机器和64位Windows机器)。

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

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

这完全是随机的,因为有时我可以连接一两个客户。其他时候一个也没有。

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

代码语言:javascript
复制
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 () ) );

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

代码语言:javascript
复制
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;
}

在服务器端,我要初始化以下代码:

代码语言:javascript
复制
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;
}

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

代码语言:javascript
复制
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,如果两个端口上没有相同的端口,消息就不会到达客户端.

很抱歉这么长的短信,但我想最好告诉你我做了什么.

如果我的代码有问题.但请记住,有时(有时)一两个客户可以真正连接.

EN

回答 1

Stack Overflow用户

发布于 2013-10-02 04:53:47

connection_status = 1;

void NetworkManager::broadcastMessageReceived中,( void )不应该出现在那里。当连接成功时,这应该在serverConnected ()中设置。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13939269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档