QT4에서 TCP 클라이언트의 IP 및 포트를 바인딩합니다. [bind QTcpSocket HOWTO]

20550 단어 socket
Author F32 ([email protected])
The code is released under the terms of GNU Lesser General Public License version 2.1
Here's the code.
 1 #ifndef Q_BOUND_TCP_SOCKET_H
2 #define Q_BOUND_TCP_SOCKET_H
3
4 #include <QTcpSocket>
5
6 /**
7 * \brief The QBoundTcpSocket class adds binding support
8 * to tcp client sockets.
9 *
10 * In Qt 4, it's impossible to bind a tcp client socket to
11 * a specific port or ip address.
12 *
13 * This feature has been added to Qt 5, however with version 4,
14 * it's still possible to do binding while getting convenience from
15 * the Qt framework.
16 *
17 * Note:
18 *
19 * Due to usage of native api, the class currently not supports
20 * platforms other than Linux. If you are familiar with
21 * native programming interfaces like winsock, porting the code
22 * to other operations systems may be just a piece of cake.
23 *
24 * A QBoundTcpSocket object will bind and connect to the server
25 * at the same time, because the only way to work around is to
26 * create a socket, bind, connect to server with native API from the
27 * OS, and then pass the socket to QTcpSocket::setSocketDescriptor
28 * with a connected state.
29 */

30
31 class QBoundTcpSocket : public QTcpSocket
32 {
33 public:
34 /**
35 * \brief Bind the socket and then connect to server
36 *
37 * Note:
38 *
39 * Before calling, the socket must be in the unconnected state,
40 * otherwise a value of false is returned.
41 *
42 * Typical usage:
43 * \code
44 * QBoundTcpSocket socket;
45 * if (socket.bindAndConnect("192.168.1.10", 0, "10.0.0.1", 80))
46 * {
47 * // Now bound and connected
48 * }
49 * else
50 * {
51 * qDebug() << "An error occurred in QBoundTcpSocket::bindAndConnect";
52 * }
53 * \endcode
54 *
55 * \param localAddr Local IP address (e.g., "10.0.0.10").
56 * A value of "0.0.0.0" indicates that
57 * the default ip address will be used.
58 * \param localPort Local port (e.g., 12345).
59 * A value of 0 indicates that any port is acceptable.
60 * \param serverAddr IP address of the server (e.g., "10.0.0.1")
61 * \param serverPort Port of the server (e.g., 80)
62 *
63 * \return The return value is true when both binding and connecting
64 * are successful, and false otherwise.
65 */

66 bool bindAndConnect(const QString &localAddr, quint16 localPort,
67 const QString &serverAddr, quint16 serverPort);
68 };
69
70 #endif /* Q_BOUND_TCP_SOCKET_H */

 
 1 #include "QBoundTcpSocket.h"
2
3 #ifdef Q_OS_LINUX
4 #include <arpa/inet.h>
5 #endif
6
7 bool QBoundTcpSocket::bindAndConnect(const QString &localAddr, quint16 localPort,
8 const QString &serverAddr, quint16 serverPort)
9 {
10 #ifdef Q_OS_LINUX
11 int sockfd;
12 int result;
13 struct sockaddr_in localSockAddr;
14 struct sockaddr_in serverSockAddr;
15 bzero(&localSockAddr, sizeof(localSockAddr));
16 bzero(&serverSockAddr, sizeof(serverSockAddr));
17
18 // create socket
19 sockfd = socket(AF_INET, SOCK_STREAM, 0);

20 if( sockfd == -1 )
21 {
22 qDebug() << "QBoundTcpSocket: Cannot create socket";
23 return false;
24 }
25
26 // bind
27 localSockAddr.sin_family = AF_INET;

28 localSockAddr.sin_port = htons(localPort);
29 localSockAddr.sin_addr.s_addr = inet_addr(localAddr.toLocal8Bit().data());
30
31 result = bind(sockfd, (struct sockaddr *)&localSockAddr, sizeof(localSockAddr));
32 if( result == -1 )
33 {
34 qDebug() << "QBoundTcpSocket: Cannot bind socket";
35 return false;
36 }
37
38 // connect
39 serverSockAddr.sin_family = AF_INET;

40 serverSockAddr.sin_port = htons(serverPort);
41 serverSockAddr.sin_addr.s_addr = inet_addr(serverAddr.toLocal8Bit().data());
42
43 result = ::connect(sockfd, (struct sockaddr *)&serverSockAddr, sizeof(serverSockAddr));
44 if( result == -1 )
45 {
46 qDebug() << "QBoundTcpSocket: Cannot connect to server";
47 return false;
48 }
49
50 // set socket descriptor
51 if( !setSocketDescriptor(sockfd, QAbstractSocket::ConnectedState))

52 {
53 qDebug() << "QBoundTcpSocket: Cannot set socket descriptor";
54 return false;
55 }
56
57 return true;
58 #else
59 qDebug() << "QBoundTcpSocket for Windows/Mac OS is not implemented yet";
60 return false;
61 #endif
62 }

좋은 웹페이지 즐겨찾기