参考
QT TCP socket通信(一)
Notes
- 继上篇Qt实现UDP通信简例 后,换成用 TCP 的版本,依旧是没有图形界面
- 注意同上篇
- client 执行
connectToHost()
后,server 的imcomingConnection()
会emit newConnection()
- server 的
close()
会调disconnectFromHost()
,它会emit disconnected()
- 此例是 server 收到信息后就主动断开连接
- 从 client 和 server 的结构看,server 本身也可以充当一个 client。要实现 P2P 既是 client 又是 server 的要求,我有一个大胆的想法:在TcpServer 里多加一个 QTcpSocket 的指针就直接当 P2P 的软件
流程
- client 向 server 发连接请求(
connectToHost()
) - server 收到请求(
newConnection()
),同意建立连接(accept_connection()
) - client 收到同意(
connected()
),向 server 发数据(send_message()
) - server 收到数据(
readyRead()
),读取并回复 client(read_and_reply()
),然后断交(close()
) - client 收到断交通知(
disconnected()
)
Code
客户端
TcpClient.h
#ifndef TCPCLIENT_H
#define TCPCLIENT_H
#include <QObject>
#include <QTcpSocket>
class TcpClient : public QObject
{
Q_OBJECT
public:
TcpClient(QObject *p = 0);
~TcpClient();
public slots:
void send_msg();
void read_msg();
void end_connent();
private:
QTcpSocket *tSocket;
};
#endif
TcpClient.cpp
#include <QByteArray>
#include <QHostAddress>
#include <QTcpSocket>
#include <iostream>
#include "tcpclient.h"
const quint16 PORT = 2333;
TcpClient::TcpClient(QObject *p) :
QObject(p)
{
tSocket = new QTcpSocket(this);
std::cout << "--- Connect to Host ---" << std::endl;
tSocket->connectToHost(QHostAddress::LocalHost, PORT);
connect(tSocket, SIGNAL(connected()),
this, SLOT(send_msg()));
connect(tSocket, SIGNAL(readyRead()),
this, SLOT(read_msg()));
connect(tSocket, SIGNAL(disconnected()),
this, SLOT(end_connent()));
}
TcpClient::~TcpClient()
{
delete tSocket;
}
void TcpClient::send_msg()
{
std::cout << "--- Successfully Connected ---\n"
<< "--- Sending Message ---"
<< std::endl;
tSocket->write(QByteArray("Hello world!"));
}
void TcpClient::read_msg()
{
QByteArray ba = tSocket->readAll();
std::cout << ba.data() << std::endl;
}
void TcpClient::end_connent()
{
std::cout << "--- Connection Ended ---" << std::endl;
}
main.cpp
#include <QCoreApplication>
#include "tcpclient.h"
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout << "--- TCP Client ---" << std::endl;
TcpClient tc;
return a.exec();
}
服务器
TcpServer.h
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include <QTcpServer>
#include <QTcpSocket>
class TcpServer : QTcpServer
{
Q_OBJECT
public:
TcpServer(QTcpServer *p = 0);
~TcpServer();
public slots:
void accept_connection();
void read_and_reply();
private:
QTcpServer *tServer;
QTcpSocket *tSocket;
};
#endif
TcpServer.cpp
#include <QByteArray>
#include <QHostAddress>
#include <iostream>
#include "tcpserver.h"
const quint16 PORT = 2333;
TcpServer::TcpServer(QTcpServer *p) :
QTcpServer(p)
{
tServer = new QTcpServer;
tSocket = new QTcpSocket;
if(tServer->listen(QHostAddress::Any, PORT))
std::cout << "--- Linsting to Port ---" << std::endl;
else
std::cout << "*** FAIL LISTING ***" << std::endl;
connect(tServer, SIGNAL(newConnection()),
this, SLOT(accept_connection()));
}
TcpServer::~TcpServer()
{
delete tServer;
delete tSocket;
}
void TcpServer::accept_connection()
{
std::cout << "--- Accept Connection ---" << std::endl;
tSocket = tServer->nextPendingConnection();
connect(tSocket, SIGNAL(readyRead()),
this, SLOT(read_and_reply()));
}
void TcpServer::read_and_reply()
{
std::cout << "--- Read Message ---" << std::endl;
QByteArray ba = tSocket->readAll();
std::cout << ba.data() << std::endl;
std::cout << "--- Reply ---" << std::endl;
tSocket->write("Nice day");
tSocket->close();
}
main.cpp
#include <QCoreApplication>
#include <iostream>
#include "tcpserver.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout << "--- TCP Server ---" << std::endl;
TcpServer ts;
return a.exec();
}
截图
工程截图
效果