TCP

来源:互联网 发布:冒险岛源码 编辑:程序博客网 时间:2024/06/16 04:40

网络通信分为阻塞和非阻塞两种,不建议采用阻塞方式。

tcpserver.cpp

#include "tcpserver.h"#include <QAbstractSocket>#include <QNetworkInterface>#include <QDataStream>TcpServer::TcpServer(){    m_socket = NULL;}void TcpServer::run(){    qDebug() << getIPAddress();    QTcpServer server;    //1.1 listen(联系linux网络编程的bind和listen)    server.listen(QHostAddress::Any, 10000);    emit signal_stateMessage(QString("listen state: %1").arg(server.isListening()));    /* waitForNewConnection: This is a blocking function call. Its use is disadvised in a single-threaded GUI application, since the whole application will stop responding until the function returns.    waitForNewConnection() is mostly useful when there is no event loop available. The non-blocking alternative is to connect to the newConnection() signal. */    //1.2 waitForNewConnection    if( !server.waitForNewConnection(30000) )    {        emit signal_stateMessage(server.errorString());        return;    }    emit signal_stateMessage(QString("waitForNewConnection successed, new connection established"));    //2. nextPendingConnection(联系linux网络编程的accept)    m_socket = server.nextPendingConnection();    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slot_error(QAbstractSocket::SocketError)));    qDebug() << m_socket;    emit signal_stateMessage(QString("%1 is connected").arg(m_socket->peerAddress().toString()));    //3. write(or read)    while (m_socket->state() & QAbstractSocket::ConnectedState)    {        m_socket->write("hello world ");        m_socket->waitForBytesWritten();        m_socket->write("bye\n");        m_socket->waitForBytesWritten();        QThread::msleep(1000);    }//    //3. write(or read)//    QByteArray block;//    QDataStream out(&block, QIODevice::ReadWrite);//    out.setVersion(QDataStream::Qt_5_5);//    out << (quint16)0;//    out << tr("hello\n");//    out.device()->seek(0);//    out << (quint16)(block.size() - sizeof(quint16));//    m_socket->write(block);//    m_socket->waitForBytesWritten();    //4. close    m_socket->close();    server.close();    emit signal_stateMessage(QString("close"));}QString TcpServer::getIPAddress(){    QString ipAddress;    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();    for (int i = 0; i < ipAddressesList.size(); ++i)    {        if (ipAddressesList.at(i) != QHostAddress::LocalHost &&            ipAddressesList.at(i).toIPv4Address())        {            ipAddress = ipAddressesList.at(i).toString();            break;        }    }    if (ipAddress.isEmpty())        ipAddress = QHostAddress(QHostAddress::LocalHost).toString();    return ipAddress;}void TcpServer::slot_error(QAbstractSocket::SocketError errormsg){//    emit signal_stateMessage(errormsg.errorString());    emit signal_stateMessage(m_socket->errorString());    //4. close    m_socket->close();//attention, close while error occurs}

tcpclient.cpp

#include "tcpclient.h"//#include <QAbstractSocket>#include <QNetworkInterface>#include <QDataStream>TcpClient::TcpClient(){//    m_socket = new QTcpSocket();//error:          Object: Cannot create children for a parent that is in a different thread.                                  //cause of error: all the memeber decfined in QThread belong to QThread's parent's thread, so m_socket which is initialized in constructor belongs to parent's thread, so that calling m_socket is cross-thread operation.                                  //solution:       move m_socket to function run}void TcpClient::run(){    QTcpSocket socket;//local var avoid memory leak    qDebug() << &socket;    //1.1 connectToHost(联系linux网络编程connect)    socket.connectToHost("localhost", 10000);    /* Note: This function may fail randomly on Windows. Consider using the event loop and the connected() signal if your software will run on Windows. */    //1.2 waitForConnected    if( !socket.waitForConnected(5000) )    {        emit signal_stateMessage(socket.errorString());        return;    }    emit signal_stateMessage(QString("waitForConnected success, connects to %1").arg(socket.peerAddress().toString()));    //2. read(or write)    while (socket.state() & QAbstractSocket::ConnectedState)    {        socket.waitForReadyRead(10000);        QString recv = QString(socket.readLine());        emit signal_message(recv);    }//    //2. read(or write)//    socket.waitForReadyRead();//    m_blockSize = 0;//    QDataStream in(&socket);//    in.setVersion(QDataStream::Qt_5_5);//    if(m_blockSize == 0)//    {//        if( socket.bytesAvailable() < (int)sizeof(quint16) )//            return;//        in >> m_blockSize;//    }//    if(socket.bytesAvailable() < m_blockSize)//        return;//    QString message;//    in >> message;//    emit signal_message(message);    //3. close    socket.close();    emit signal_stateMessage(QString("close"));}