2017-09-13 8 views
1

私はUDPを介していくつかのデバイスと通信する必要があります。問題は、の特別な場合なしでQUdpSocketがまったく動作しないということです。私はconnectToHost()メソッドfor access to read()/write() functionsを使用します。QUdpSocketがバインドなしで動作しない

コードを使用するときに交換が全く機能していないUDP:

m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);  
m_udp.waitForConnected(); 

のIは、任意のバイトを受信しません。 Wiresharkの中のメッセージ:

QUdpSocket error in Wireshark

以下のコードは、あまりにも動作しません:

m_udp.bind(4001); 
m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);  
m_udp.waitForConnected(); 

をしかし、コードが唯一のQt 5.6で動作します:

m_udp.bind(QHostAddress("192.168.100.15"), 4001); 
m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);  
m_udp.waitForConnected(); 

のみ、このコードは動作します。 Qt 5.4.2では動作しません。ここ は、私が受信しようとする方法である:

dev->waitForReadyRead(500); 
QByteArray ba = dev->readAll(); 

振る舞いはとても奇妙であるのはなぜ?どのようにこれを理解することができますか?

答えて

2

あなたは反対側のコードを示していないが、どうやら示すwiresharkのイメージから、リモートピアがあなたのソケットが最初のコードスニペットが接続しようとするポート4001

に拘束されることに期待していますローカルポートを指定せずに(RemoteAddress、4001)カーネルが任意のポート番号(wiresharkによる64875)を割り当てますが、上記のようにもう一方の側はで、がポート4001に返信されることを期待しています。ポート番号64875で受信してください。

UDPでは、実際の接続のようなものはありません。connectToHostを使用すると、あなたは本当にonlですリモート側のIPアドレスとポート番号を指定します。リモート側が正しいポートに送り返すことを確認するのはアプリケーションの責任です。これは、(a)常に特定のポートに送信すること(ここでは明らかに行われているように)、または(b)相手側がデータグラムが実際に受信されたアドレス/ポートを調べてそれを返すことによって行うことができます。言い換えると、リモート側は、受信したデータグラムがポート64875から送信され、そのポートへの応答をターゲットにしていると判断できます。

2回目の試行では、ローカルエンドポイントを他のマシンのアドレスにバインドしようとしていますが、これは意味をなさないだけです。 (ローカルマシンのIPアドレスであるm_udp.bind(QHostAddress("192.168.100.3"), 4001);にバインドを変更した場合、このスニペットが動作すると思われます)

IPアドレスを指定せずにローカルポート4001にバインドしているので、リモートマシンのポート4001に送信することもできます。 bindにポート番号だけを指定すると、IPアドレスは「ワイルドカード」のままになります。そのため、マシンのIPアドレスのいずれかでそのポート番号にパケットを送信する必要があります。

(あなたはQtの以前のバージョンで異なる動作を見られる理由は考え。)

1

でも書き込みまたは読み出し前に結合した後、ソケットの状態を確認してください。

このコードを参照してください:いくつかのことがうまくいかない場合

QHostAddress serverIP("172.168.1.100"); 
if(socket->bind(serverIP,port,QUdpSocket::ShareAddress)) //even if local Host dont have static IP(on subnet expected 172.168.x.x),still it becomes true and enters if. 
    { 
    if((socket->state() == QAbstractSocket::BoundState) && (((socket->localAddress()).protocol()) == QAbstractSocket::IPv4Protocol)) //ignore protocol validation if not required. 
     { 

     } 
else 
     { 
      qDebug()<<"Socket not in bound state. address is: "<<QHostAddress::LocalHost<<" and the port "<<port; 
      //Return = false; 
     } 
    } 
else 
    { 
     qDebug()<<"Failed to bind socket to the address "<<QHostAddress::LocalHost<<" and the port "<<port; 
     //Return = false; 
    } 

第二に、Qtの中のソケットは、エラー信号を出力します。だから、それらのエラー信号を捕まえるためのスロットが必要です。この方法で、問題の背後にある理由を知ることができます。例のため

:sockerエラーを受信する

connect(udpsocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(onSocketError(QAbstractSocket::SocketError))); 

スロット:

void SomeInterface::onSocketError(QAbstractSocket::SocketError socketError) 
{ 
    qDebug()<<"socket error occured and the error is : "<<socketError; 
} 
関連する問題