#include "tcpclient.h" #include #include #include TcpClient::TcpClient(QObject *parent) : QObject(parent), m_pClientSocket(NULL), m_pConnectCheckTimer(NULL), m_connected(0), m_pConnectDetect(NULL), m_detect(0), m_localip(DEF_LOCAL_IP), m_localport(DEF_LOCAL_PORT), m_serverip(DEF_SERVER_IP), m_serverport(DEF_SERVER_PORT) { m_pClientSocket = new QBindTcpSocket(this); m_pClientSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1); connect(m_pClientSocket, SIGNAL(readyRead()), this, SLOT(receiveServerData())); connect(m_pClientSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displaySocketError(QAbstractSocket::SocketError))); // connect(m_pClientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(netStateChanged(QAbstractSocket::SocketState))); m_pConnectCheckTimer = new QTimer(this); connect(m_pConnectCheckTimer, SIGNAL(timeout()), this, SLOT(connectCheck())); } TcpClient::~TcpClient() { if(m_pClientSocket !=NULL) { m_pClientSocket->disconnectFromHost(); m_pClientSocket->waitForDisconnected(); m_pClientSocket->close(); delete m_pClientSocket; m_pClientSocket = NULL; } if(m_pConnectCheckTimer != NULL) { m_pConnectCheckTimer->stop(); delete m_pConnectCheckTimer; m_pConnectCheckTimer = NULL; } } void TcpClient::setIpAndPort(QString serverIp, quint16 serverPort, QString localIp, quint16 localPort) { m_serverip = serverIp; m_serverport = serverPort; m_localip = localIp; m_localport = localPort; } void TcpClient::connectToServer() { if (m_pClientSocket == NULL) { qDebug() << "m_pClientSocket not alloc"; return; } if (m_connected == 0) { if (m_pConnectDetect == NULL) { m_pConnectDetect = new TcpConnectDetect; } qDebug() << "ConnectToServer"; qDebug() << "localip=" << m_localip << "localport=" << m_localport; qDebug() << "serverip=" << m_serverip << "serverport=" << m_serverport; m_pConnectDetect->setIpAndPort(m_localip, m_localport, m_serverip, m_serverport); connect(this, SIGNAL(siDetectHost()), m_pConnectDetect, SLOT(connectDetect()), Qt::QueuedConnection); connect(m_pConnectDetect, SIGNAL(siConnectSta(int)), this, SLOT(detectStatus(int)), Qt::QueuedConnection); m_pConnectCheckTimer->start(1000); m_connected = 1; m_detect = 1; } } void TcpClient::disConnectFromServer() { if (m_connected != 0) { m_pConnectCheckTimer->stop(); if (m_pClientSocket != NULL) { m_pClientSocket->disconnectFromHost(); m_pClientSocket->waitForDisconnected(); m_pClientSocket->close(); } m_connected = 0; m_detect = 0; } } // 发送数据的槽 void TcpClient::slotSendData(QByteArray dat) { if (m_pClientSocket != NULL) { m_pClientSocket->write(dat); } } // 自动检测连接 void TcpClient::connectCheck() { if (m_pClientSocket == NULL) { qDebug() << "Socket is not alloced"; return; } // qDebug() << "check client connect"; if (m_connected == 1) { if (m_localip.isEmpty() == false) { m_pClientSocket->bindAddrAndPort(m_localip, m_localport); } m_pClientSocket->abort(); m_pClientSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1); m_pClientSocket->connectToHost(m_serverip, m_serverport); int rslt = m_pClientSocket->waitForConnected(2000); if (rslt == 0) { } /* qDebug("bind connect and waitForConnected 2000, rslt=%d", rslt); qDebug() << "localip=" << m_localip << "localport=" << m_localport; qDebug() << "serverip=" << m_serverip << "serverport=" << m_serverport; */ m_connected = 2; } else if (m_connected != 0) { switch(m_pClientSocket->state()) { case QAbstractSocket::ConnectedState: { if (m_connected != 3) { /* qDebug() << "net State is Connected"; qDebug() << "localip=" << m_localip << "localport=" << m_localport; */ m_connected = 3; // 检测连接状态 } break; } case QAbstractSocket::ConnectingState: { if (m_connected != 2) { qDebug() << "net State is Connecting"; // qDebug() << "localip=" << m_localip << "localport=" << m_localport; } m_connected = 2; break; } case QAbstractSocket::UnconnectedState: { if (m_connected != 1) { // qDebug() << "net State is unconnected"; // qDebug() << "localip=" << m_localip << "localport=" << m_localport; } m_connected = 1; break; } default: { /* QAbstractSocket::HostLookupState QAbstractSocket::BoundState QAbstractSocket::ListeningState QAbstractSocket::ClosingState */ { qDebug("net State is %d\r\n", m_pClientSocket->state()); qDebug() << "localip=" << m_localip << "localport=" << m_localport; qDebug() << "serverip=" << m_serverip << "serverport=" << m_serverport; } m_connected = 1; } } } else { } if (m_connected == 3) // 已连接 { if (m_detect == 1) { // qDebug() << "Machine " << QThread::currentThread(); m_detect = 0; emit(siDetectHost()); // qDebug() << "after send SiDetectHost "; } } emit (siConnectSta(m_connected)); // 网络连接信号 } void TcpClient::detectStatus(int sta) { // qDebug("host detect sta=%d", sta); m_detect = 1; if (sta == 1) // 网络已断开 { qDebug("disconnect ClientSocket by detect"); m_pClientSocket->disconnectFromHost(); // m_pClientSocket->waitForDisconnected(); m_pClientSocket->close(); m_connected = 1; } else if (sta == 2) // 网络连接还在 { } else { } } void TcpClient::receiveServerData() { if (m_pClientSocket != NULL) { QByteArray tmpDat; tmpDat = m_pClientSocket->readAll(); // 读取 // qDebug("ReceiveServerData, size = %d", tmpDat.size()); // PrintAsHex(&tmpDat); emit(siReceiveData(tmpDat)); // 发送收到数据信号 } } void TcpClient::displaySocketError(QAbstractSocket::SocketError err) { QString errinfo; errinfo.sprintf("Err: code=%d, errorString=", err); errinfo += m_pClientSocket->errorString(); // qDebug() << errinfo; emit(siConnectErr(errinfo)); // 网络错误信息 } void TcpClient::netStateChanged(QAbstractSocket::SocketState sta) { switch (sta) { /* case UnconnectedState: case HostLookupState: case ConnectingState: case ConnectedState: case BoundState: case ListeningState: case ClosingStat: */ default: break; } } void TcpClient::hostFound() { qDebug("found host"); } #if(0) //------------------------------------------------------- TcpConnectDetect::TcpConnectDetect(QObject *parent) : QObject(parent), m_pDetectSocket(NULL), m_localip(DEF_LOCAL_IP), m_localport(DEF_LOCAL_PORT), m_serverip(DEF_SERVER_IP), m_serverport(DEF_SERVER_PORT) { } TcpConnectDetect::~TcpConnectDetect() { if (m_pDetectSocket == NULL) { m_pDetectSocket->disconnectFromHost(); m_pDetectSocket->waitForDisconnected(); m_pDetectSocket->close(); delete m_pDetectSocket; } } void TcpConnectDetect::detectStart() { qDebug("TcpConnectDetect start"); if (m_pDetectSocket == NULL) { m_pDetectSocket = new QBindTcpSocket; } } int TcpConnectDetect::connectDetect() { int connectsta = 0; int rslt; // qDebug() << "TcpConnectDetect " << QThread::currentThread(); if (m_pDetectSocket == NULL) { return 0; } if (m_localip.isEmpty() == false) { m_pDetectSocket->bindAddrAndPort(m_localip, m_localport); } m_pDetectSocket->abort(); m_pDetectSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1); m_pDetectSocket->connectToHost(m_serverip, m_serverport); do { rslt = m_pDetectSocket->waitForConnected(4000); // 等待连接 qDebug("bind Detect connect rslt=%d", rslt); qDebug() << "localip=" << m_localip << "localport=" << m_localport; qDebug() << "serverip=" << m_serverip << "serverport=" << m_serverport; switch(m_pDetectSocket->state()) { case QAbstractSocket::ConnectedState: { // 如果连接上,说明 m_pClientSocket 连接已经无效, 需要断开重新连接 // 先断开测试连接 m_pDetectSocket->disconnectFromHost(); m_pDetectSocket->waitForDisconnected(); connectsta = 1; // 发送断开主连接的信号 qDebug() << "detect is Connected, disconnect all"; break; } case QAbstractSocket::UnconnectedState: { // qDebug() << "detect is Unconnected err=" << m_pDetectSocket->error() << ", info:" << m_pDetectSocket->errorString(); switch (m_pDetectSocket->error()) { case QAbstractSocket::SocketTimeoutError: // 连接超时,说明已经断开 case QAbstractSocket::NetworkError: // 网络错误, 主机不可连接, 可能已经断开 { qDebug() << "detect is timout, disconnect all"; connectsta = 1; // 发送断开主连接的信号 break; } case QAbstractSocket::ConnectionRefusedError: // 拒绝连接, 说明连接还在 { connectsta = 2; // qDebug() << "Connection Refused, old connect is alive"; break; } /* case QAbstractSocket::RemoteHostClosedError: case QAbstractSocket::HostNotFoundError: case QAbstractSocket::SocketAccessError: case QAbstractSocket::SocketResourceError: case QAbstractSocket::SocketTimeoutError: case QAbstractSocket::DatagramTooLargeError: case QAbstractSocket::AddressInUseError: case QAbstractSocket::SocketAddressNotAvailableError: case QAbstractSocket::UnsupportedSocketOperationError: case QAbstractSocket::UnfinishedSocketOperationError: case QAbstractSocket::ProxyAuthenticationRequiredError: case QAbstractSocket::SslHandshakeFailedError: case QAbstractSocket::ProxyConnectionRefusedError: case QAbstractSocket::ProxyConnectionClosedError: case QAbstractSocket::ProxyConnectionTimeoutError: case QAbstractSocket::ProxyNotFoundError: case QAbstractSocket::ProxyProtocolError: case QAbstractSocket::UnknownSocketError: */ default: { // 继续检测 connectsta = 2; qDebug() << " retry"; break; } } // 错误处理结束 } case QAbstractSocket::ConnectingState: { // qDebug() << "detect is Connecting"; // qDebug() << "localip=" << m_localip << "localport=" << m_localport; // 继续等待 break; } case QAbstractSocket::HostLookupState: case QAbstractSocket::BoundState: case QAbstractSocket::ListeningState: case QAbstractSocket::ClosingState: default: { // 继续等待 qDebug("detect sta is %d\r\n", m_pDetectSocket->state()); break; } } if (connectsta != 0) { break; } }while(1); m_pDetectSocket->close(); // 发送本次测试连接的状态信号 emit(siConnectSta(connectsta)); return connectsta; } void TcpConnectDetect::setIpAndPort(QString localip, quint16 localport, QString serverip, quint16 serverport) { m_localip = localip; m_localport = localport; m_serverip = serverip; m_serverport = serverport; } #endif