文档章节

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

J
 JosephVS
发布于 2015/07/26 10:35
字数 1310
阅读 2273
收藏 2

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

 

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

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

 

一个服务器的建立,必须要有对外双向通讯的接口就是套接字(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

© 著作权归作者所有

共有 人打赏支持
J
粉丝 0
博文 1
码字总数 1310
作品 0
杭州
私信 提问
[Qt] 基于Tcp协议的聊天室实现

时间:2017年6月21日 一、写在前面: 平时做图形学的东西多一些,虽然一直对网络编程很感兴趣,但是没有什么机会去尝试一下。最近正好赶上期末的课程实习,然后就参考Qt官方的 Network Prog...

Mahabharata_
2017/06/22
0
0
我的简历,大家帮忙看看,欢迎大家提建议

求职意向 c/c++程序员(网络开发) 个人信息 姓名:**** 性别:男 出生年月:1989.10 学历:本科 专业:信息系统与信息管理 毕业学校:西北农林科技大学 电话:153 1948 **** 电子邮箱:dwl...

谈秦论晋
2011/08/20
1K
23
哎,路还很长呀,.........ㄒoㄒ

我翻阅了许多网络编程方面的书箱,经常可以看到“在局域网下的文字聊天”“在局域网下的视频聊天”这样的字样。但是我用了其中的代码,发现有时用本机在公网的IP也能连接,但有时也连接不上。...

jinx88
2016/07/23
13
0
Python基础教程,第十五讲,网络编程(一)Socket详解

网络编程的重要性不低于数据库操作,而且两者通常是同时存在,比如用python写一个爬虫程序,最终抓取的数据保存入库,写了一个web项目,用户注册,登录,提交订单等数据最终也要保存到我们的...

程序员补给栈
01/25
0
0
用QT作的最简单的局域网聊天工具

用QT作的最简单的局域网聊天工具。。。我是想要源代码的~~就是实现局域网之间的聊天工具~谁有帮忙一下~!!新手求教,简单一点的好。如果只有界面的代码也可以~!后多或少有帮助的都可以~求大...

xeinstein
2012/05/11
3.8K
3

没有更多内容

加载失败,请刷新页面

加载更多

总结:线程间频繁切换为什么耗费资源?

因为线程切换的时候,CPU需要将此线程的所有执行状态保存起来,如线程编号,执行到的位置等,然后再去执行其它线程。

浮躁的码农
26分钟前
0
0
PHP版本高于5.5时,curl文件上传必须使用CurlFile对象

坑了我一天,之前@的方法各种上传不成功文件。都怀疑服务端有bug了。

叫我哀木涕
26分钟前
0
0
js算法总结

数列求和 等差数列求和 function sum(a0,d,n){//a0->首项,d->公差,n->项数//(首项+末项)*项数/2return (a1+(a1+d*n))*n/2;} 等比数列求和 function sum(a0,q,n){//a0->首项,q->公......

祖达
51分钟前
2
0
小白?转型?毕业生?外行学习快速入行大数据开发指南

这篇文章中,本文将针对三种不同的、想要进入数据科学领域的人群,给出自己的经验,帮助他们迅速有效入行。 虽然没有适合每个人的万能解决方案,但这三类建议值得想转行的你一看。 第1类:新...

董黎明
59分钟前
1
0
好文 | MySQL 索引B+树原理,以及建索引的几大原则

MySQL事实上使用不同的存储引擎也是有很大区别的,下面猿友们可以了解一下。 一、存储引擎的比较 注:上面提到的B树索引并没有指出是B-Tree和B+Tree索引,但是B-树和B+树的定义是有区别的。 ...

Java爬坑之路
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部