关于Qt网络编程
QTcpServer用于创建TCP服务器端。当newConnection信号激发时,我们调用指定的槽创建一个通信的套接字。
QTcpSocket用于创建TCP通信套接字。当connected信号激发时,我们向服务器端发送消息,当readyRead信号激发时,我们就可以读取数据了。
本程序中网络对战的实现
本程序封装了QTcpServer和QTcpSocket来实现网络对战的功能。服务器端实现类为ServerNetwork,客户端实现类为ClientNetwork。整个流程大致如下:
(1)服务器端监听套接字。
void ServerNetwork::initServer(int port)
{
server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
if(!server->listen(QHostAddress::Any, port))
{
QMessageBox::critical(NULL, tr("错误信息"), tr("监听端口失败!"));
}
}
(2)客户端连接服务器。
void ClientNetwork::initClient(QString serverIP, int port)
{
clientSocket = new QTcpSocket();
connect(clientSocket, SIGNAL(connected()), this, SLOT(connected()));
connect(clientSocket, SIGNAL(disconnected()),this, SLOT(disconnected()));
connect(clientSocket, SIGNAL(disconnected()), clientSocket, SLOT(deleteLater()));
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData()));
connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
QHostAddress addr(serverIP);
clientSocket->connectToHost(addr, port);
}
(3)客户端连接上服务器后,服务器创建与客户端通信的套接字,客户端发送请求获取游戏信息。
void ServerNetwork::newConnection()
{
serverSocket = server->nextPendingConnection();
connect(serverSocket, SIGNAL(disconnected()), this, SLOT(disconnected()));
connect(serverSocket, SIGNAL(disconnected()), serverSocket, SLOT(deleteLater()));
connect(serverSocket, SIGNAL(readyRead()), this, SLOT(readData()));
emit connStateChanged(true);
}
void ClientNetwork::connected()
{
emit connStateChanged(true);
MsgReqGameInfo msg;
clientSocket->write((char *)&msg, sizeof(msg));
}
(4)双方等待套接字上有数据可读,并进行消息处理。
void ClientNetwork::readData()
{
char msg[1024];
memset(msg, 0, 1024);
int len = clientSocket->read(msg, 1024);
emit processMessage(msg, len);
}
void ServerNetwork::readData()
{
char msg[1024];
memset(msg, 0, 1024);
int len = serverSocket->read(msg, 1024);
emit processMessage(msg, len);
}
整个过程还是相当简单的。与C语言api相比,Qt提供的类要方便得多。