2015-06-25 91 views
0

我想建立一個QTcpSocket連接。我正在研究一個簡單的應用程序,它涉及通過單個TCP套接字進行雙向通信。QTcpSocket未連接

我通過運行同一個應用程序的兩個實例並連接到QHostAddress :: Broadcast來測試我的代碼。當我運行我的代碼,我得到國家的順序如下:

  1. QAbstractSocket :: HostLookupState - 「套接字進行主機名查找。」
  2. QAbstractSocket :: ConnectingState - 「套接字已經開始建立連接。」
  3. QAbstractSocket :: UnconnectedState - 「套接字未連接」。
  4. QAbstractSocket :: SocketError - 「權限被拒絕」。

編輯:一些進一步的調試之後,我發現,第4項實際上是一個連接被拒絕錯誤

下面是我的代碼:

#include "widget.h" 
#include "ui_widget.h" 
#include <string> 

Widget::Widget(QWidget *parent) : 
    QWidget(parent), 
    ui(new Ui::Widget) 
{ 
    ui->setupUi(this); 
} 

Widget::~Widget() 
{ 
    delete ui; 
} 

void Widget::on_connect_clicked() 
{ 
    if (!m_socket) 
    { 
     m_socket = new QTcpSocket(this); 
     m_socket->setSocketOption(QAbstractSocket::KeepAliveOption,1); 
    } 

    connect(m_socket, SIGNAL(readyRead()), SLOT(readSocketData()), Qt::UniqueConnection); 
    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(connectionError(QAbstractSocket::SocketError)), Qt::UniqueConnection); 
    connect(m_socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), SLOT(tcpSocketState(QAbstractSocket::SocketState)), Qt::UniqueConnection); 
    connect(m_socket, SIGNAL(disconnected()), SLOT(onConnectionTerminated()), Qt::UniqueConnection); 
    connect(m_socket, SIGNAL(connected()), SLOT(onConnectionEstablished()), Qt::UniqueConnection); 

    if(!(QAbstractSocket::ConnectedState == m_socket->state())) 
    { 
     m_socket->connectToHost(QHostAddress::Broadcast, ui->port->value(), QIODevice::ReadWrite); 
    } 

} 

void Widget::readSocketData() 
{ 
    while(m_socket->bytesAvailable()) 
    { 
     QTextStream T(m_socket); 
     ui->incoming->addItem(T.readAll()); 
    } 
} 


void Widget::on_send_clicked() 
{ 
    sendMessage(ui->message->text()); 
} 

void Widget::sendMessage(QString msg) 
{ 
    QByteArray dataSend; 
    QDataStream dataStream(&dataSend, QIODevice::WriteOnly); 
    dataStream.setByteOrder(QDataStream::LittleEndian); 
    dataStream << msg.length(); 
    dataSend.append(msg); 

    m_socket->write(dataSend, dataSend.length()); 
} 

void Widget::connectionError(QAbstractSocket::SocketError socketError) 
{ 
    std::string errorStr = "ERROR: " + m_socket->errorString().toStdString(); 
    QMessageBox::information(this, tr("Tcp Server Client"), tr(errorStr.c_str())); 
} 

void Widget::tcpSocketState(QAbstractSocket::SocketState socketState) 
{ 
    switch (socketState) { 
     case QAbstractSocket::UnconnectedState: 
      QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket is not connected.")); 
      break; 
     case QAbstractSocket::HostLookupState: 
      QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket is performing a hostname lookup.")); 
      break; 
     case QAbstractSocket::ConnectedState: 
      QMessageBox::information(this, tr("Tcp Server Client"), tr("A connection is established.")); 
      break; 
     case QAbstractSocket::ConnectingState: 
      QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket has started establishing a connection.")); 
      break; 
     case QAbstractSocket::BoundState: 
      QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket is bound to an address and port.")); 
      break; 
     case QAbstractSocket::ClosingState: 
      QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket is about to close.")); 
      break; 
     case QAbstractSocket::ListeningState: 
      QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket is listening.")); 
      break; 
     default: 
      QMessageBox::information(this, tr("Tcp Server Client"), tr("Unknown State.")); 
    } 
} 

void Widget::onConnectionTerminated() 
{ 
    QMessageBox::information(this, tr("Tcp Server Client"), tr("Disconnected.")); 
} 

void Widget::onConnectionEstablished() 
{ 
    QMessageBox::information(this, tr("Tcp Server Client"), tr("Connected!")); 
} 

我將不勝感激大大如果有人可以幫助我找出爲什麼這個錯誤可能會來了。我是Qt和網絡的新手,所以我可能會有一些相當明顯的缺失。

在此先感謝!

回答

0

其實還有就是你缺少一個基本的事情:能夠連接到你需要有一個正在上,聽的過程的插座地址和端口。 因此,您實際上可以使用同一軟件的兩個實例進行連接,但其中一個實例必須充當服務器(並偵聽),第二個實例必須嘗試進行連接。 到目前爲止,您只實現了第二部分。

所以,你應該加入類似:

void Widget::on_listen_clicked() 
{ 
    if (!m_socket->listen()) { 
     QMessageBox::information(this, tr("Tcp Server"),tr("Error listening!")); 
    } 
} 

當然,你需要對你的小部件一聽按鈕,並用它在你運行的實例之一。

0

您不能在TCP上使用廣播地址。因此,您可以選擇單播地址(指向單個目標的地址),也可以使用QUdpSocket

你可以找到這兩種情況下的文檔中的例子:http://doc.qt.io/qt-5/examples-network.html

+0

我試過QHostAddress :: LocalHost(我相信它是單播的),並且我遇到了同樣的問題。有沒有可能是我失蹤的其他東西?謝謝! – mtwister

+0

我試圖通過以太網電纜連接兩臺電腦並輸入相應的IP地址。我仍然有同樣的問題。所以我認爲我的代碼有其他錯誤... – mtwister

+0

你打開了你試圖連接到本地(對於本地主機)還是在其他計算機上的端口(例如,使用'QTcpServer'及其'listen'功能,或任何其他服務器軟件)? – alexisdm