Qt学习心得之网络编程简单的局域网聊天服务端建立

学而不思则罔,思而不学则殆。学习和思考是相辅相成的,通过这几天对网络编程的学习,收获颇丰。接下来我将利用Qt做的一个以TcpIp协议为传输方式的简单的局域网聊天服务端与大家分享下:

 

首先谈谈我个人对Tcp协议的理解:Tcp就是网上购物,买家和买家之间的物品传递,快递公司的扮演。快递公司将卖家所要寄出的物品进行包装,给予独特的号码,并从卖家获取目的地地址,得知这些明确信息后准确将物品送到买家,买家签收后,卖家通过快递单号查询到买家签收的消息。

其次是这个简单局域网聊天服务器的创建思路。如下图是思路的框图:

Qt学习心得之网络编程简单的局域网聊天服务端建立_第1张图片 

一个服务器的建立,必须要有对外双向通讯的接口就是套接字(socket),所以需要建一个Mysocket的类,这样才可以将不同客户端的消息发给其他客户端。之后还需要再创建一个Myserver的类,将每个客户端发送的消息通过Mysocket发送信号被接受。然后在每个客户端对应的每个Myserver中将各自发送的信号发送给其他客户端,并再发送给serverUI界面上显示。如图:在MysocketMyserver以及Myserverserver之间的联系都是通过发送信号,并利用槽函数进行处理,所以这整个程序的关键是合理运用信号和槽函数,将信息顺利传达。

然后是程序的展示和一些关键点的处理方式。

//========================Mysocket.c=============================//

MyTcpSocket::MyTcpSocket(QObject *parent) :/*在构造函数中进行信号和槽函数的连接*/

    QTcpSocket(parent)

{

    connect(this,SIGNAL(readyRead()),     /*读信号和对应的槽函数处理*/

            SLOT(slotReadyread()));

    connect(this,SIGNAL(disconnected()),   /*断开连接的信号和对应的槽函数处理*/

            SLOT(slotDisconnect()));

}

void MyTcpSocket::slotReadyread()      

{

    QString msg;                    

    QByteArray ba;        /*采用QByteArray字节数组的方式客户端发送消息进行读取* /

    ba.resize(this->bytesAvailable());    /*判断是否可读*/

    this->read(ba.data(),ba.size());      /*读取客户端发送的消息*/

    msg=QString(ba);         /*将接收到的消息转化为QString类型*/

    emit updatemsg(msg,this->socketDescriptor(),this->peerAddress().toString());/*将客户端的信息通过信号的方式发送出去(信号包括客户端输入内容、客户端对应的描述符以及客户端的IP地址)*/

}

void MyTcpSocket::slotDisconnect()   

{

    qDebug("Disconnect host");     

    emit signalDisconnect(this->socketDescriptor()); /*将断开的客户端所对应的描述符信号发送出去*/

}

//========================Myserver.c=============================//

MyTcpserver::MyTcpserver(QObject *parent) :   /*在构造函数中监听*/    QTcpServer(parent)

{

    listen(QHostAddress::Any,8080);/*监听任何客户端IP地址的连入,以及端口号为8080*/

/**/

}

void MyTcpserver::incomingConnection(qintptr socketDescriptor){/*incomingConnection这个函数在服务端被客户端连接上后自动调用此函数,传入的参数为该客户端特有的描述符*/

    qDebug("incomingConnection");

    MyTcpSocket* sock = new MyTcpSocket;   /*新建一个Mysocket的对象*/

    sock->setSocketDescriptor(socketDescriptor); /*设置sock的描述符*/

    connect(sock,SIGNAL(signalDisconnect(qintptr)),   

            this,SLOT(slotDisconnect(qintptr))); /*断开连接的信号和对应的槽函数处理*/

    connect(sock,SIGNAL(updatemsg(QString,qintptr,QString)),  

            this,SLOT(slotupdatemsg(QString,qintptr,QString)));/*Mysocket发送过来客户端的信息进行处理,用于发送给UI界面*/

    connect(sock,SIGNAL(updatemsg(QString,qintptr,QString)),

            this,SLOT(slotrecivermsg(QString,qintptr,QString)));/*Mysocket发送过来客户端的信息进行处理,再发送给其他连入的客户端*/

 

    clients << sock; /*创建的一个QList的容器类名为clients,将每个不同的客户端放入到该容器中,以便后续处理*/

}

void MyTcpserver::slotDisconnect(qintptr sockfd)/*断开槽函数处理主要是将断开的客户端从容器中移除*/

{

    int i=0;

    for(i=0;i<clients.count();i++){              /*遍历容器中存入的客户端*/

        if(clients.at(i)->socketDescriptor()==sockfd){/*当找到容器中对应的那个断开的客户端后,将其移除*/

            clients.removeAt(i);

            break;

        }

    }

}

void MyTcpserver::slotupdatemsg(QString msg,qintptr sockfd,QString IP)

{

    qDebug()<<"slotupdatemsgServer";

    emit updatemsgServer(msg,IP);   /*将客户端信息通过信号的方式传送给UI界面*/

}

void MyTcpserver::slotrecivermsg(QString msg,qintptr sockfd,QString IP)

{

        QString message;

        message=IP+" : "+msg;     /*设定回复给其他客户端的信息格式*/

        int i=0;

        for(i=0;i<clients.count();i++){

            if(clients.at(i)->socketDescriptor()!=sockfd){ /*遍历容器中存入的客户端*/

                clients.at(i)->write(message.toLatin1(),message.length());/*将消息发送给除自己以外的所有连入的客户端*/

 

            }

        }

}

//========================server.c=============================//

tcpserver::tcpserver(QWidget *parent) :  /*在构造函数中进行信号和槽函数的连接*/

    QWidget(parent),

    ui(new Ui::tcpserver)

{

    ui->setupUi(this);       

    server = new MyTcpserver;   /*新建一个MyTcpserver对象*/

    connect(server,SIGNAL(updatemsgServer(QString,QString)),

            this,SLOT(recivermsg(QString,QString)));/*MyTcpservert发送过来客户端的信息进行界面显示处理*/

 

}

 

tcpserver::~tcpserver()  /*析构函数中释放ui*/

{

    delete ui;

}

void tcpserver::recivermsg(QString msg,QString IP)

{

    qDebug("recivermsg");

    qDebug()<<msg;

    ui->listWidget->addItem(IP+" : "+msg);  /*显示发送的信号到UI界面上*/

}

最后感谢汇文,在汇文培训学习也有三个多月了,在这个融洽的大家庭中,感觉每天都很充实,在学习中实践,在实践中收获,愿自己在将来能找到一份合适的工作。附上汇文网站可供浏览:www.huiwen.com

你可能感兴趣的:(网络编程,qt,局域网聊天)