QTcpServer *tcpserver; QTcpSocket *tcpsocket;这两个类是必须的(对于服务器而言)。
其中QTcpServer 主要用于服务器端建立网络“监听”
“创建网络Socket”连接。一般监听网络连接需要ip地址+端口。
当有新的客户端连接时,会发射newConnect()信号
当客户端和服务器端的链接建立后就通过QTcpSocket 来传输数据。
接下来我们来创建一个简单的客户端和服务器端的链接,文字发送的小程序。
服务器端:
大致可以分为四部分,part1:首先我们得建立链接,通过ip地址和端口来实现对于客户端接入的监听:
tcpserver = new QTcpServer(this);
quint16 port = tcpserver->serverPort();
QHostAddress add(ip);
tcpserver->listen(add,port);
Part2:对于新接入的链接需要监听,这里我们使用connect来监听。
connect(tcpserver,SIGNAL(newConnection()),this,SLOT(onNewConnetc()));
onNewConnetc()函数我们用来写当新链接接入后我们要干的内容,比如给一写提示啊啥玩意的。
QString ip = getlocaleip();
tcpsocket = tcpserver->nextPendingConnection();
connect(tcpsocket,SIGNAL(connected()),this,SLOT(onClientConnect()));
connect(tcpsocket,SIGNAL(disconnected()),this,SLOT(DisClientConnect()));
connect(tcpsocket,SIGNAL(readyRead()),this,SLOT(onReadReady()));
程序首先通过nextPendingConnection()函数获取与接入连接进行通信的QTcpSocket对象实例tcpSocket,
connected()信号 客户端socket连接建立时发射此信号
disconnected()信号 客户端socket连接断开时发射此信号
stateChange(),本程序得到socket状态变化时发射此信号
readyRead(),本程序的socket的读取缓冲区有新数据时发射此信号
我们在onClientConnect()函数中只需要简单的弄些链接成功的提示就行了
void MainWindow::onClientConnection()
{
//当客户端接入时
ui->plainTextEdit->appendPlainText("client socket connected");
ui->plainTextEdit->appendPlainText("***peer address:"+tcpsocket->peerAddress().toString());
ui->plainTextEdit->appendPlainText("**peer port:"+tcpsocket->peerPort());
}
在DisClientConnect()中除去链接提示,还需要销毁链接。
void MainWindow::onClientDisconnected()
{
//当客户端断开连接时
ui->plainTextEdit->appendPlainText("**client socket disconnected");
tcpsocket->deleteLater();//销毁对象
}
这些都相对来说好理解和实现。也不是啥核心或重要部分。接下来的数据输入才是重要部分:
我们通过一个action的槽函数来实现消息的输出:
主体的思路是这样的,将ui中获取的信息转换成字节流,然后使用write函数写入即可:
void MainWindow::on_btn_send_msg_clicked()
{
//发送一行字符,以换行符结束
QString msg = ui->lineEdit->text();
ui->plainTextEdit->appendPlainText("[out] "+msg);
ui->lineEdit->clear();
ui->lineEdit->setFocus();
QByteArray str = msg.toUtf8();//将字符串转换成数据流
str.append('\n');
tcpsocket->write(str);
}
到此信息的传出已经完成了。但是我们最好需要把信息显示出来,这个时候就需要readready()函数了。
void MainWindow::onReadReady()
{
while(tcpsocket->canReadLine())
ui->plainTextEdit->appendPlainText("[in]:"+tcpsocket->readLine());
}
至此,服务器端的部分就完成了。
网络连接部分:1客户端的布置
客户端这块现对于服务器端简单些,客户端的重点就在于如何链接到服务器端。我们使用connectToHost()函数来实现客户端和服务器端的链接。
void MainWindow::on_act_link_triggered()
{
QString ip = getlocaleip();
quint16 port = ui->lineEdit_port->text().toInt();
QHostAddress add(ip);
tcpsocket->connectToHost(add,port);
connect(tcpsocket,SIGNAL(connected()),this,SLOT(onNewConnetc()));
connect(tcpsocket,SIGNAL(disconnected()),this,SLOT(DisClientConnect()));
connect(tcpsocket,SIGNAL(readyRead()),this,SLOT(onReadReady()));
}
客户端的connected()函数,disconnected(),readyRead()函数可以类比服务器端的函数。当客户端链接到服务器时,我们激活onNewConnetc(),可以在该函数中输出一些已经链接的信息啥的,打印客户端的端口号和ip地址。
onReadReady()函数和服务器端的大同小异,毕竟都是信息的传输。
void MainWindow::onReadReady()
{
while(tcpsocket->canReadLine())
ui->plainTextEdit->appendPlainText("[out]:"+tcpsocket->readLine());
}
信息的发送这块也和服务器端的一样即可。至此,客户端的开发也完成了!
一定要先运行服务器端,在运行客户端!