QT4 TcpSocket bind问题

转自http://www.cnblogs.com/F-32/archive/2012/03/23/2414204.html

Author F32 (feng32@163.com)

The code is released under the terms of GNU Lesser General Public License version 2.1

Here's the code.


#ifndef Q_BOUND_TCP_SOCKET_H  
#define Q_BOUND_TCP_SOCKET_H  
  
#include <QTcpSocket>  
  
/** 
 * \brief The QBoundTcpSocket class adds binding support 
 * to tcp client sockets. 
 * 
 * In Qt 4, it's impossible to bind a tcp client socket to 
 * a specific port or ip address. 
 * 
 * This feature has been added to Qt 5, however with version 4,  
 * it's still possible to do binding while getting convenience from 
 * the Qt framework. 
 *  
 * Note: 
 *  
 * Due to usage of native api, the class currently not supports 
 * platforms other than Linux. If you are familiar with  
 * native programming interfaces like winsock, porting the code 
 * to other operations systems may be just a piece of cake. 
 *  
 * A QBoundTcpSocket object will bind and connect to the server 
 * at the same time, because the only way to work around is to 
 * create a socket, bind, connect to server with native API from the 
 * OS, and then pass the socket to QTcpSocket::setSocketDescriptor 
 * with a connected state. 
 */  
  
class QBoundTcpSocket : public QTcpSocket  
{  
public:  
    /** 
     * \brief Bind the socket and then connect to server 
     * 
     * Note: 
     *  
     * Before calling, the socket must be in the unconnected state,  
     * otherwise a value of false is returned. 
     *  
     * Typical usage: 
     * \code 
     * QBoundTcpSocket socket; 
     * if (socket.bindAndConnect("192.168.1.10", 0, "10.0.0.1", 80)) 
     * { 
     *     // Now bound and connected 
     * } 
     * else 
     * { 
     *     qDebug() << "An error occurred in QBoundTcpSocket::bindAndConnect"; 
     * } 
     * \endcode 
     * 
     * \param localAddr Local IP address (e.g., "10.0.0.10"). 
     *                  A value of "0.0.0.0" indicates that  
     *                  the default ip address will be used. 
     * \param localPort Local port (e.g., 12345).  
     *                  A value of 0 indicates that any port is acceptable. 
     * \param serverAddr IP address of the server (e.g., "10.0.0.1") 
     * \param serverPort Port of the server (e.g., 80) 
     * 
     * \return The return value is true when both binding and connecting  
     *         are successful, and false otherwise. 
*/  
     bool bindAndConnect(const QString &localAddr, quint16 localPort,   
                         const QString &serverAddr, quint16 serverPort);  
};  
  
#endif /* Q_BOUND_TCP_SOCKET_H */  

  

#include "QBoundTcpSocket.h"  
  
#ifdef Q_OS_LINUX  
    #include <arpa/inet.h>  
#endif  
  
bool QBoundTcpSocket::bindAndConnect(const QString &localAddr, quint16 localPort,   
                                     const QString &serverAddr, quint16 serverPort)  
{  
#ifdef Q_OS_LINUX  
    int sockfd;  
    int result;  
    struct sockaddr_in localSockAddr;  
    struct sockaddr_in serverSockAddr;  
    bzero(&localSockAddr, sizeof(localSockAddr));  
    bzero(&serverSockAddr, sizeof(serverSockAddr));  
      
    // create socket  
    sockfd = socket(AF_INET, SOCK_STREAM, 0);  
    if( sockfd == -1 )   
    {  
        qDebug() << "QBoundTcpSocket: Cannot create socket";  
        return false;  
    }  
      
    // bind  
    localSockAddr.sin_family = AF_INET;  
    localSockAddr.sin_port = htons(localPort);  
    localSockAddr.sin_addr.s_addr = inet_addr(localAddr.toLocal8Bit().data());  
  
    result = bind(sockfd, (struct sockaddr *)&localSockAddr, sizeof(localSockAddr));  
    if( result == -1 )   
    {  
        qDebug() << "QBoundTcpSocket: Cannot bind socket";  
        return false;  
    }  
      
    // connect  
    serverSockAddr.sin_family = AF_INET;  
    serverSockAddr.sin_port = htons(serverPort);  
    serverSockAddr.sin_addr.s_addr = inet_addr(serverAddr.toLocal8Bit().data());  
  
    result = ::connect(sockfd, (struct sockaddr *)&serverSockAddr, sizeof(serverSockAddr));  
    if( result == -1 )   
    {  
        qDebug() << "QBoundTcpSocket: Cannot connect to server";  
        return false;  
    }  
      
    // set socket descriptor  
    if( !setSocketDescriptor(sockfd, QAbstractSocket::ConnectedState))  
    {  
        qDebug() << "QBoundTcpSocket: Cannot set socket descriptor";  
        return false;  
    }  
      
    return true;  
#else  
    qDebug() << "QBoundTcpSocket for Windows/Mac OS is not implemented yet";  
    return false;  
#endif  
}  

  

posted @ 2018-03-09 16:06  blackld  阅读(654)  评论(0编辑  收藏  举报