沧州三亚菏泽经济预测自然
投稿投诉
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产
菏泽德阳
山西湖州
宝鸡上海
茂名内江
三亚信阳
长春北海
西安安徽
黄石烟台
沧州湛江
肇庆鹤壁
六安韶关
成都钦州

Qt开发TCPIP网络通信

8月12日 相见欢投稿
  TCPIP通信(即SOCKET通信)是通过网线将服务器Server端和客户机Client端进行连接,在遵循ISOOSI模型的四层层级构架的基础上通过TCPIP协议建立的通讯。控制器可以设置为服务器端或客户端。
  关于TCPIP协议可详看:TCPIP协议详解知乎(zhihu。com)
  总的来说,TCPIP通讯有两个部分:客户端和服务器QTcpServer(监听套接字)和QTcpSocket(通讯套接字)
  监听套接字,顾名思义,监听关于各种通讯的状态,一旦进行通讯,监听套接字会启动通讯套接字,进行通讯
  客户端使用connectToHost函数主动连接服务器后,服务器会触发newConnectio这个槽函数,并进行取出QTcpServer(监听套接字),将相关内容取出并赋给QTcpSocket(通讯套接字)。
  客户端向服务器发送数据,触发readyRead(),进行处理,彼此传递时,原理都是这样的。
  对双方来说都起作用的部分:一旦建立连接,就会触发connected,服务器特殊一点,触发的是newConnectio互传数据也是一样的,一旦接受到,就会触发readyread
  服务器中,需要监听套接字以及通讯套接字,监听套接字用于监听客户端是否给服务器发送请求
  本篇博文做了初步的学习与尝试,编写了一个客户端和服务器基于窗口通信以及文件传输的小例程。一,客户端
  客户端的代码比服务器稍简单,总的来说,使用QT中的QTcpSocket类与服务器进行通信只需要以下5步:
  (1)创建QTcpSocket套接字对象socketnewQTcpSocket(this);
  (2)使用这个对象连接服务器QStringipui。lineEditiptext();获取ipintportui。lineEdit2text()。toInt();获取端口数据socketconnectToHost(ip,port);
  (3)使用write函数向服务器发送数据QByteArraydataui。lineEdit3text()。toUtf8();获取lineEdit控件中的数据并发送给服务器socketwrite(data);
  (4)当socket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据connect(socket,QTcpSocket::readyRead,this,QTcpClinet::ReadData);voidQTcpClinet::ReadData(){QByteArraybufsocketreadAll();ui。textEditappend(buf);}
  (5)断开与服务器的连接(关于close()和disconnectFromHost()的区别,可以按F1看帮助)socketdisconnectFromHost();
  客户端例程:(新建一个qt项目QTcpClinet(客户机))ui界面
  本地回路ip:127。0。0。1可以连接到本地ip(电脑内部循环的ip)
  如果要和局域网其他ip连接在运行(winR)cmdipconfigipv4地址查看本机ip
  点击领取Qt学习资料视频教程链接
  QTcpClinet。hincludeQtWidgetsQWidgetincludeuiQTcpClinet。hincludeQTcpSocket。hpragmaexecutioncharacterset(utf8)classQTcpClinet:publicQWidget{QOBJECTpublic:QTcpClinet(QWidgetparentQNULLPTR);QTcpClinet();publicslots:voidonbtnconnectclicked();voidReadData();voidonbtnpushclicked();private:Ui::QTcpClinetCQTcpS创建socket指针};QTcpClinet。cppincludeQTcpClinet。hQTcpClinet::QTcpClinet(QWidgetparent):QWidget(parent){ui。setupUi(this);socketnewQTcpSocket(this);}QTcpClinet::QTcpClinet(){回收内存}voidQTcpClinet::onbtnconnectclicked(){if(ui。btnconnecttext()tr(连接服务器)){QStringipui。lineEditiptext();获取ipintportui。lineEdit2text()。toInt();获取端口数据取消已有的连接socketabort();连接服务器socketconnectToHost(ip,port);boolisconnectsocketwaitForConnected();等待直到连接成功如果连接成功if(isconnect){ui。textEditappend(Theconnectionwassuccessful!!);ui。btnpushsetEnabled(true);按钮使能修改按键文字ui。btnconnectsetText(断开服务器连接);接收缓冲区(服务器)信息connect(socket,QTcpSocket::readyRead,this,QTcpClinet::ReadData);}else{ui。textEditappend(Theconnectionfalied!!);}}else{断开连接socketdisconnectFromHost();ui。btnconnectsetText(连接服务器);ui。btnpushsetEnabled(false);关闭发送按钮使能}}接收缓冲区信息函数voidQTcpClinet::ReadData(){QByteArraybufsocketreadAll();ui。textEditappend(buf);}发送按钮事件voidQTcpClinet::onbtnpushclicked(){QByteArraydataui。lineEdit3text()。toUtf8();获取lineEdit控件中的数据并发送给服务器socketwrite(data);判断是否写入成功booliswritesocketwaitForBytesWritten();if(iswrite){写入成功}else{没有写入成功}}二,服务器(需要一直运行哦)
  服务器除了使用到了QTcpSocket类,还需要用到QTcpSever类。即便如此,也只是比客户端复杂一点点,用到了6个步骤:
  (1)创建QTcpSever对象servernewQTcpServer(this);
  (2)侦听一个端口,使得客户端可以使用这个端口访问服务器serverlisten(QHostAddress::Any,6677);监听所有ip和6677端口
  (3)当服务器被客户端访问时,会发出newConnection()信号,因此为该信号添加槽函数,并用一个QTcpSocket对象接受客户端访问connect(server,QTcpServer::newConnection,this,TcpServer::ClientConnect);voidTcpServer::ClientConnect(){解析所有客户连接while(serverhasPendingConnections()){连接上后通过socket(QTcpSocket对象)获取连接信息socketservernextPendingConnection();QStringstrQString(〔ip:1,port:2〕)。arg(socketpeerAddress()。toString())。arg(socketpeerPort());监听客户端是否有消息发送connect(socket,QTcpSocket::readyRead,this,TcpServer::ReadData1);}}
  (4)使用socket的write函数向客户端发送数据socketwrite(data);
  (5)当socket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据监听客户端是否有消息发送connect(socket,QTcpSocket::readyRead,this,TcpServer::ReadData1);获取客户端向服务器发送的信息voidTcpServer::ReadData1(){QByteArraybufsocketreadAll();readAll最多接收65532的数据QStringstrQString(〔ip:1,port:2〕)。arg(socketpeerAddress()。toString())。arg(socketpeerPort());ui。textEditserverappend(strQString(buf));socketwrite(ok);服务器接收到信息后返回一个ok}
  (6)取消侦听serverclose();
  服务器例程:(添加一个新的qt项目TcpServer(服务器))ui界面TcpServer。hincludeQtWidgetsQWidgetincludeuiTcpServer。hincludeqtcpserver。hincludeqtcpsocket。hclassTcpServer:publicQWidget{QOBJECTpublic:TcpServer(QWidgetparentQNULLPTR);TcpServer();publicslots:voidonbtnserverclicked();voidonbtnlistenclicked();private:Ui::TcpServerCQTcpSQTcpS一个客户端对应一个socketvoidClientConnect();voidReadData1();};TcpServer。cppincludeTcpServer。hincludeqstring。hincludeqdebug。hpragmaexecutioncharacterset(utf8)TcpServer::TcpServer(QWidgetparent):QWidget(parent){ui。setupUi(this);servernewQTcpServer(this);客户机连接信号槽connect(server,QTcpServer::newConnection,this,TcpServer::ClientConnect);}TcpServer::TcpServer(){serverclose();serverdeleteLater();}voidTcpServer::onbtnlistenclicked(){if(ui。btnlistentext()侦听){从输入框获取端口号intportui。lineEditporttext()。toInt();侦听指定端口的所有ipif(!serverlisten(QHostAddress::Any,port)){若出错,则输出错误信息qDebug()servererrorString();}修改按键文字ui。btnlistensetText(取消侦听);}else{socketabort();取消侦听serverclose();修改按键文字ui。btnlistensetText(侦听);}}voidTcpServer::ClientConnect(){解析所有客户连接while(serverhasPendingConnections()){连接上后通过socket获取连接信息socketservernextPendingConnection();QStringstrQString(〔ip:1,port:2〕)。arg(socketpeerAddress()。toString())。arg(socketpeerPort());提示连接成功ui。textEditserverappend(strConnecttotheserver);复选框选项为连接服务器的ipui。comboBoxaddItem(str);将socket地址放入combobox属性内ui。comboBoxsetItemData(ui。comboBoxcount()1,QVariant((int)socket));监听客户端是否有消息发送connect(socket,QTcpSocket::readyRead,this,TcpServer::ReadData1);}}获取客户端向服务器发送的信息voidTcpServer::ReadData1(){QByteArraybufsocketreadAll();readAll最多接收65532的数据QStringstrQString(〔ip:1,port:2〕)。arg(socketpeerAddress()。toString())。arg(socketpeerPort());ui。textEditserverappend(strQString(buf));}服务器向客户端发送信息voidTcpServer::onbtnserverclicked(){if(ui。comboBoxcount()0)QTcpSocketskt(QTcpSocket)ui。comboBoxitemData(ui。comboBoxcurrentIndex())。valueint();socketwrite(ui。lineEdit1text()。toUtf8());}
  注意:write中需要写入char类型的元素或QByteArray类型的元素
  效果展示:
  三,TCPIP文件传输
  上文实现了消息的传输,由于socketreadAll();(readAll最多接收65532的数据),因此对于大文件的传输用此方法是不可取的。
  点击领取Qt学习资料视频教程链接
  TCPIP文件传输的思路:客户端和服务器连接客户端选择文件,并发送文件给服务器(发送的是文件的帧头,格式:文件名大小)服务器触发readyRead,然后解析文件帧头(获取文件名和大小),并返回客户端一个ok消息客户端触发readyRead,然后发送文件数据,通过progressBar显示进度服务器再次触发readyRead,接收文件数据,并保存(通过ishead判断接收的是文件帧头还是文件数据)
  代码实现:
  新建服务器项目(TcpServer)TcpServer。hpragmaonceincludeQtWidgetsQWidgetincludeuiTcpServer。hincludeqtcpserver。hincludeqtcpsocket。hpragmaexecutioncharacterset(utf8)classTcpServer:publicQWidget{QOBJECTpublic:TcpServer(QWidgetparentQNULLPTR);voidhasConnect();private:Ui::TcpServerCQTcpSQTcpSQStringfileNintfileS接收文件的总大小intrecvS当前接收文件的大小QByteA当前接收的文件数据};TcpServer。cppincludeTcpServer。hincludeqfile。hTcpServer::TcpServer(QWidgetparent):QWidget(parent){ui。setupUi(this);servernewQTcpServer(this);监听1122端口的ipserverlisten(QHostAddress::Any,1122);如果有用户连接触发槽函数connect(server,QTcpServer::newConnection,this,TcpServer::hasConnect);}voidTcpServer::hasConnect(){while(serverhasPendingConnections()0)判断当前连接了多少人{用socket和我们的客户端连接,一个客户端对应一个套接字socketsocketservernextPendingConnection();服务器界面上输出客户端信息ui。textEditappend(QString(1:新用户连接)。arg(socketpeerPort()));如果客户端发送信息过来了,触发匿名函数connect(socket,QTcpSocket::readyRead,〔〕(){QByteArraybufsocketreadAll();用一个标志位ishead判断是头还是数据位if(ishead){如果是头,解析头(文件名,文件大小)QStringstrQString(buf);ui。textEditappend(str);QStringListstrliststr。split();fileNamestrlist。at(0);解析帧头文件名fileSizestrlist。at(1)。toInt();解析帧头文件大小下次接收到的文件就是我们的数据recvSize0;filebuf。clear();socketwrite(ok);}else{根据文件名和文件大小接收和保存文件filebuf。append(buf);recvSizebuf。size();每接收一次文件,当前文件大小1当接收文件大小等于总文件大小,即文件数据接收完毕if(recvSizefileSize){保存文件QFilefile(ui。lineEdittext()fileName);file。open(QIODevice::WriteOnly);file。write(filebuf);file。close();}}});}}
  新建客户端项目(QTcpClient)QTcpClient。hincludeQtWidgetsQWidgetincludeuiQTcpClient。hincludeqtcpsocket。hpragmaexecutioncharacterset(utf8)classQTcpClient:publicQWidget{QOBJECTpublic:QTcpClient(QWidgetparentQNULLPTR);publicslots:voidonbtnconnectclicked();voidonbtnchooseclicked();voidonbtnopenclicked();private:Ui::QTcpClientCQTcpS};QTcpClient。cppincludeQTcpClient。hincludeqfiledialog。hincludeqfileinfo。hQTcpClient::QTcpClient(QWidgetparent):QWidget(parent){ui。setupUi(this);socketnewQTcpSocket(this);}voidQTcpClient::onbtnconnectclicked(){QStringipui。lineEditiptext();获取ipintportui。lineEditporttext()。toInt();获取端口数据socketconnectToHost(ip,port);连接服务器等待连接成功if(socketwaitForConnected()){ui。textEditappend(fontcolorgreen连接服务器成功!font);ui。btnopensetEnabled(true);如果服务器发送信息到客户端,触发匿名函数connect(socket,QTcpSocket::readyRead,〔〕(){读取服务器发送的信息(即缓冲区信息)QByteArraybufsocketreadAll();if(bufok){QFilefile(ui。labelpathtext());if(!file。open(QIODevice::ReadWrite)){读取文件失败}qint64currentlen0;当前已经发送的大小qint64allLengthfile。size();总文件大小do{chardata〔1024〕;qint64msizefile。read(data,1024);读文件放入打他数组中,返回读取到的大小socketwrite(data,msize);把读取到的data数据发送给服务器实时获取当前发送的文件大小ui。progressBarsetValue(currentlen100allLength);更新界面进度条}while(currentlenallLength);当发送文件等于文件大小时,发送完毕,循环结束}});}else{ui。textEditappend(fontcolorred连接服务器失败!font);}}选择文件事件voidQTcpClient::onbtnchooseclicked(){QStringpathQFileDialog::getOpenFileName(this,打开文件,,(。));ui。labelpathsetText(path);}发送文件事件voidQTcpClient::onbtnopenclicked(){QFileInfoinfo(ui。labelpathtext());用QFileInfo::fileName,size获取文件名和大小格式:文件名大小服务器用该格式解析文件名和大小QStringheadQString(12)。arg(info。fileName())。arg(info。size());将该格式发送给服务器toUtf8:QString转QByteArray或char类型socketwrite(head。toUtf8());}
  效果展示:
投诉 评论

(体育)斯诺克巡回锦标赛丁俊晖止步半决赛新华社伦敦3月31日电(记者张薇)中国名将丁俊晖31日以5:10不敌凯威尔逊,止步斯诺克巡回锦标赛半决赛。威尔逊则将与塞尔比和墨菲之间的胜者争冠。斯诺克巡回锦标赛由本赛季……加入方大半年,新海航发生速变如何帮助深陷危机的企业走出困境?如何克服新一轮新冠肺炎疫情对行业的影响?这是带领海南航空开启新征程之初,辽宁方大集团首先要迎接的两个挑战。去年12月8日,旗下拥有海南航空……财政部不得通过国企购地等方式虚增土地出让收入财政部关于加强三公经费管理严控一般性支出的通知财预〔2022〕126号各中央预算单位,各省、自治区、直辖市、计划单列市财政厅(局),新疆生产建设兵团财政局:坚……Qt开发TCPIP网络通信TCPIP通信(即SOCKET通信)是通过网线将服务器Server端和客户机Client端进行连接,在遵循ISOOSI模型的四层层级构架的基础上通过TCPIP协议建立的通讯。控……你对NFC了解多少?是否会用,现在就告诉你1NFC是什么?NFC全称是NearFieldCommunication,即近场通信,也叫近距离无线通信。它是非接触式射频识别(RFID)技术的基础上,结合无线互联技术研……2023春节换机推荐,公认的3款近乎零差评手机,随便用三年春节已经过了几天了,今天给大家推荐三款最值得考虑入手的手机,主要是公认的近乎零差评,评论多,好评还高,随便用三年不成问题。红米K50可能会有不少人觉得红米K60已经发布了……女人40以后,如果不差钱的话,建议买这5款大牌面霜,滋润又抗女人40岁以后,肌肤已经逐渐步入熟龄肌的行列,也是要真正开始进行抗老护肤的阶段。在这一阶段内,选择的抗老产品需要兼顾效果和肤感,如果能够在短时间内改善皮肤问题是更好的。4……李敏与毛主席回忆相认往事,毛主席笑称我不认你你就没得爸爸呀前言1940年冬,毛泽东决定将女儿娇娇(即李敏)送往苏联,送到她的母亲贺子珍身边,这一年李敏只有4岁,她与朱德的女儿朱敏一起坐上飞机,东看看这个,西看看那个,好奇个不停,……恺英网络目前已有一款动作竞技类VR游戏在研发中11月12日,恺英网络(002517)在互动平台回答投资者提问时表示,公司于2022年年初成立了VR游戏团队,目前已有一款动作竞技类VR游戏在研发中,未来公司将持续加强在VR游……陈亚男短视频账号被封,靠蹭大衣哥流量赚钱的美梦破灭了陈亚男进入直播领域已经有一年多了,为了赚钱,她多个平台撒网,在ks、DY等平台都有账号,前不久,陈亚男的DY直播间被封,后靠道歉和回归朱楼村才得以解封,但谁能想到,紧接着,陈亚……迪马利亚祝贺梅西达成国家队百球,你是当之无愧的队长昨天早上结束的国际友谊赛,阿根廷70大胜库拉索,梅西上演帽子戏法,将自己的国家队进球数刷新至102粒。迪马利亚在本场比赛替补上场,制造点球并主罚命中。赛后,迪马利亚更新I……数据中心成耗能大户,如何开源节流?绿色发展是21世纪人类发展的共同追求,也是新时代中国发展的重要理念之一。2021年7月,工业和信息化部印发的《新型数据中心发展三年行动计划(20212023年)》中提出,新建大……
网游里的消费陷阱你中过多少恐怖新作TheKindemanRemedy公布疯狂医生恐怖实黄河壶口瀑布迎来桃花汛女性腰背疼关节酸凉,3个食疗方法,帮助止痛全明星不要了,盖帽王也不要了!被伤病拖垮的伪强队,好聚好散吧老年人营养不良易被忽视?重点提示来了!沃尔玛扛不住业绩下跌!六折大清仓,顾客薅羊毛上瘾买17双鞋只八生给我的警醒(随笔)新鲜早科技丨谷歌迎额外反垄断诉讼Rivian召回几乎所有车辆一帧秒创结合chatGTP,助力高效图文转视频!世界著名的十大陨石坑这些自然景观,你见过吗车满为患滴滴这个坑别往里面跳了

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找