如何使用QT5编写一个利用TCP协议的聊天室 (二)编写一个TCP的客户端

前言

客户端相对于服务器端而言,比较简单(服务器端的实现可以查看我的上一篇文字).服务器端主要分为两个功能:1.建立服务器端的连接2.将数据发送到服务器的套接字中

具体实现

1.建立服务器端的连接

首先我们得知道与谁建立连接,所以我们需要一个QHostAddress的对象来检验我们输入的目标ip地址可否使用,然后用一个QTcpSocket的对象来使用connectToHost()函数来与目标建立连接,该函数接受两个参数,第一个参数为ip地址,第二个参数为端口.当函数使用后,服务器端便可以监听到我们的接入.

2.将数据发送到服务器的套接字中

使用与读取数据相反的函数wirte()函数便可实现这一操作,wirte()函数同样由QTcpSocket的对象来调用,该函数接受两个参数,第一个参数为存储所以发送的数据的变量,第二个参数为所以发送的字节数.

具体代码

以下代码为.cpp中的部分代码,代码参考<<Qt5开发及实例(第三版)>>,若内容有错误理解希望能提出指正

TcpClient::TcpClient(QWidget *parent,Qt::WindowFlags f)
    : QDialog(parent,f)
{
    //界面初始化
    setWindowTitle(tr("TCP Client"));
    contentListWiget = new QListWidget;
    sendLineEdit = new QLineEdit;
    sendBtn = new QPushButton(tr("Send out"));
    userNameLabel = new QLabel(tr("user name:"));
    userNameLineEdit = new QLineEdit;
    serverIPLabel = new QLabel(tr("The server address:"));
    serverIPLineEdit = new QLineEdit;
    portLabel = new QLabel(tr("port "));
    portLineEdit = new QLineEdit;
    enterBtn = new QPushButton(tr("enter the chat room"));
    mainLayout = new QGridLayout(this);
    mainLayout->addWidget(contentListWiget,0,0,1,2);
    mainLayout->addWidget(sendLineEdit,1,0);
    mainLayout->addWidget(sendBtn,1,1);
    mainLayout->addWidget(userNameLabel,2,0);
    mainLayout->addWidget(userNameLineEdit,2,1);
    mainLayout->addWidget(serverIPLabel,3,0);
    mainLayout->addWidget(serverIPLineEdit,3,1);
    mainLayout->addWidget(portLabel,4,0);
    mainLayout->addWidget(portLineEdit,4,1);
    mainLayout->addWidget(enterBtn,5,0,1,2);

    status = false;//status表示当前状态,true表示已经进入聊天室,false表示离开聊天室
    port = 8010;//将端口与服务器设为一致
    portLineEdit->setText(QString::number(port));
    serverIP = new QHostAddress();//初始化一个QHostaddress的对象
    connect(enterBtn,SIGNAL(clicked()),this,SLOT(slotEnter()));
    connect(sendBtn,SIGNAL(clicked()),this,SLOT(slotSend()));
    sendBtn->setEnabled(false);
}

TcpClient::~TcpClient()
{

}

void TcpClient::slotEnter()
{
    if(!status)
    {
        QString ip = serverIPLineEdit->text();//获取文本框中的地址
        if(!serverIP->setAddress(ip))//将获取的名字与地址进行验证
        {
            QMessageBox::information(this,tr("error"),tr("server ip address error!"));
            return;
        }
        if(userNameLineEdit->text()=="")
        {
            QMessageBox::information(this,tr("error"),tr("User name error"));
            return;
        }
        userName = userNameLineEdit->text();
        tcpSocket = new QTcpSocket(this);//初始化一个QTcpSocket的对象
        connect(tcpSocket,SIGNAL(connected()),this,SLOT(slotConnected()));//当连接成功后connected()发出信号
        connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));//当连接断开后disconnected()发出信号
        connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(dateReceived()));//当服务器端传回信息时更新文本框内容
        tcpSocket->connectToHost(*serverIP,port);//建立与目标ip,端口的连接
        status = true;
    }
    else {
        int length =0;
        QString msg = userName+tr(":Leave chat room");
        if((length = tcpSocket->write(msg.toLatin1(),msg.length()))!=msg.length())//将Leave chat room字符串发送给服务器
        {
            return;
        }
        tcpSocket->disconnectFromHost();//尝试关闭套接字
        status = false;
    }
}
void TcpClient::slotConnected()//接受到连接成功后的信号,将"Enter chat room"字符串发送至服务器
{
    sendBtn->setEnabled(true);
    enterBtn->setText(tr("leave"));
    int length=0;
    QString msg = userName+tr(" Enter chat room");
    if((length = tcpSocket->write(msg.toLatin1(),msg.length()))!=msg.length())
    {
        return;
    }
}
void TcpClient::slotSend()//当按下发送键后读取文本框的内容发送给服务器
{
    if(sendLineEdit->text()=="")
    {
        return;
    }
    QString msg = userName+" : "+sendLineEdit->text();
    tcpSocket->write(msg.toLatin1(),msg.length());
    sendLineEdit->clear();
}
void TcpClient::slotDisconnected()//断开连接后使连接按钮能再次被按下
{
    sendBtn->setEnabled(false);
    enterBtn->setText("Enter chat room");
}
void TcpClient::dateReceived()//当服务器传来消息时读取数据,更新文本框
{
    while (tcpSocket->bytesAvailable()>0) {
        QByteArray datagram;
        datagram.resize(tcpSocket->bytesAvailable());
        tcpSocket->read(datagram.data(),datagram.size());
        QString msg = datagram.data();
        contentListWiget->addItem(msg.left(datagram.size()));
    }
}

 

上一篇:Qt网络编程学习(获取本机网络信息)


下一篇:python udp协议发送接收数据