軟件設(shè)計(jì)TCPIP網(wǎng)絡(luò)通信程序設(shè)計(jì)實(shí)驗(yàn)報(bào)告.docx
《軟件設(shè)計(jì)TCPIP網(wǎng)絡(luò)通信程序設(shè)計(jì)實(shí)驗(yàn)報(bào)告.docx》由會(huì)員分享,可在線閱讀,更多相關(guān)《軟件設(shè)計(jì)TCPIP網(wǎng)絡(luò)通信程序設(shè)計(jì)實(shí)驗(yàn)報(bào)告.docx(41頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、南京郵電大學(xué)通信與信息工程學(xué)院課程設(shè)計(jì)報(bào)告201 /201 學(xué)年 第二學(xué)期課程設(shè)計(jì) 實(shí)驗(yàn)報(bào)告模 塊 名 稱 TCP/IP網(wǎng)絡(luò)通信程序設(shè)計(jì)專 業(yè) 學(xué) 生 班 級(jí) 學(xué) 生 學(xué) 號(hào) 學(xué) 生 姓 名 指 導(dǎo) 教 師 QT5.6環(huán)境下的源代碼目 錄題目1獲取計(jì)算機(jī)的名稱和IP地址11、設(shè)計(jì)內(nèi)容12、設(shè)計(jì)分析論述及程序?qū)崿F(xiàn)流程框圖13、關(guān)鍵實(shí)現(xiàn)代碼及注解24、程序運(yùn)行測(cè)試與結(jié)果45、程序設(shè)計(jì)中遇到的問題及改進(jìn)思路4題目2基本C/S模式的通信實(shí)驗(yàn)51、設(shè)計(jì)內(nèi)容52、設(shè)計(jì)分析論述及程序?qū)崿F(xiàn)流程框圖53、關(guān)鍵實(shí)現(xiàn)代碼及注解84、程序運(yùn)行測(cè)試與結(jié)果215、程序設(shè)計(jì)中遇到的問題及改進(jìn)思路23題目3簡(jiǎn)單的瀏覽器的實(shí)現(xiàn)
2、241、設(shè)計(jì)內(nèi)容242、設(shè)計(jì)分析論述及程序?qū)崿F(xiàn)流程框圖243、關(guān)鍵實(shí)現(xiàn)代碼及注解254、程序運(yùn)行測(cè)試與結(jié)果265、程序設(shè)計(jì)中遇到的問題及改進(jìn)思路28題目4利用smtp協(xié)議發(fā)送郵件291、設(shè)計(jì)內(nèi)容292、設(shè)計(jì)分析論述及程序?qū)崿F(xiàn)流程框圖293、關(guān)鍵實(shí)現(xiàn)代碼及注解304、程序運(yùn)行測(cè)試與結(jié)果375、程序設(shè)計(jì)中遇到的問題及改進(jìn)思路38課程設(shè)計(jì)小節(jié)39附錄4039題目1獲取計(jì)算機(jī)的名稱和IP地址1、設(shè)計(jì)內(nèi)容獲取計(jì)算機(jī)的名稱和IP地址實(shí)驗(yàn) 編寫程序?qū)崿F(xiàn)下述功能:獲取計(jì)算機(jī)的名稱和IP地址2、設(shè)計(jì)分析論述及程序?qū)崿F(xiàn)流程框圖 Qt Creator是一個(gè)用于Qt開發(fā)的輕量級(jí)跨平臺(tái)集成開發(fā)環(huán)境。Qt Creator
3、可帶來兩大關(guān)鍵益處:提供首個(gè)專為支持跨平臺(tái)開發(fā)而設(shè)計(jì)的集成開發(fā)環(huán)境 (IDE),并確保首次接觸Qt框架的開發(fā)人員能迅速上手和操作。即使不開發(fā)Qt應(yīng)用程序,Qt Creator也是一個(gè)簡(jiǎn)單易用且功能強(qiáng)大的IDE。Qt數(shù)據(jù)庫(kù)中提供QtNetwork Module中的QHostInfo、QHostAddress、QNetworkInterface和QNetAddressEntry等類來查詢網(wǎng)絡(luò)參數(shù)。QNetworkInterface類提供了程序所運(yùn)行的主機(jī)IP地址和網(wǎng)絡(luò)接口信息的列表,在一個(gè)網(wǎng)絡(luò)接口信息中,包含一個(gè)或多個(gè)IP地址,每一個(gè)IP地址又包含和它相關(guān)的子網(wǎng)掩碼和廣播地址。它們?nèi)邉e封裝在一個(gè)
4、對(duì)象中QNetworkAddressEntry,網(wǎng)絡(luò)接口信息也包含了硬件地址信息。1完成界面getHostInformation()函數(shù)獲得主機(jī)信息slotDetail()函數(shù)網(wǎng)絡(luò)接口信息運(yùn)行出結(jié)果3、關(guān)鍵實(shí)現(xiàn)代碼及注解1. 在NetworkInformation.pro文件中,添加QT += network2. 在頭文件networkinformation.h中添加如下代碼:#include #include public:void getHostInformation();public slots:void slotDetail();對(duì)QHostInfo、QNetworkInterface
5、進(jìn)行聲明,添加槽函數(shù)。3. 在源文件networkinformation.cpp中添加代碼。其中在構(gòu)造函數(shù)的最后添加:getHostInformation(); /用于獲得主機(jī)信息connect(detailBtn,SIGNAL(clicked(),this,SLOT(slotDetail();4. getHostInformation()函數(shù)用于獲得主機(jī)信息。具體實(shí)現(xiàn)代碼如下:void NetworkInformation:getHostInformation() QString localHostName = QHostInfo:localHostName();/獲得本機(jī)主機(jī)名 LineE
6、ditLocalHostName-setText(localHostName); QHostInfo hostInfo = QHostInfo:fromName(localHostName);/根據(jù)主機(jī)名獲得相關(guān)主機(jī)信息,包括IP地址等。QHostInfo:fromName()函數(shù)通過主機(jī)名查找IP地址信息。 QList listAddress = hostInfo.addresses();/獲得主機(jī)的IP地址列表 if(!listAddress.isEmpty()/獲得的主機(jī)IP地址列表可能為空。在不為空的情況下使用第一個(gè)IP地址。 LineEditAddress-setText(listA
7、ddress.first().toString(); 注釋見上。25. slotDetail()函數(shù)獲得與網(wǎng)絡(luò)接口相關(guān)的信息,具體實(shí)現(xiàn)代碼如下:void NetworkInformation:slotDetail()/獲得與網(wǎng)絡(luò)接口相關(guān)的信息 QString detail=; QList list=QNetworkInterface:allInterfaces();/QNetworkInterface類提供了一個(gè)主機(jī)IP地址和網(wǎng)絡(luò)接口的列表 for(int i=0;ilist.count();i+) QNetworkInterface interface=list.at(i); detail=
8、detail+u8設(shè)備:+interface.name()+n;/獲得網(wǎng)絡(luò)接口的名稱 detail=detail+u8硬件地址:+interface.hardwareAddress()+n;/獲得網(wǎng)絡(luò)接口的硬件地址 QList entryList=interface.addressEntries(); /每個(gè)網(wǎng)絡(luò)接口包括0個(gè)或多個(gè)IP地址,每個(gè)IP地址有選擇性地與一個(gè)子網(wǎng)掩碼和(或)一個(gè)廣播地址相關(guān)聯(lián) /QNetworkAddressEntry類存儲(chǔ)了被網(wǎng)絡(luò)接口支持的一個(gè)IP地址,同時(shí)還包括與之相關(guān)的子網(wǎng)掩碼和廣播地址 for(int j=0;jentryList.count();j+) QN
9、etworkAddressEntry entry=entryList.at(j); detail=detail+t+u8IP 地址:+entry.ip().toString()+n; detail=detail+t+u8子網(wǎng)掩碼:+mask().toString()+n; detail=detail+t+u8廣播地址:+entry.broadcast().toString()+n; QMessageBox:information(this,tr(Detail),detail);4、程序運(yùn)行測(cè)試與結(jié)果 圖1-1 獲取本機(jī)網(wǎng)絡(luò)信息 圖1-2 獲取本機(jī)詳細(xì)網(wǎng)絡(luò)信息5、程序設(shè)計(jì)中遇到的問題及改進(jìn)思路1
10、. “詳細(xì)”這個(gè)按鈕單擊時(shí),沒有明顯的痕跡,故后期添加了一些特效。將PushButton的屬性checkable設(shè)置為真,則運(yùn)行時(shí)鼠標(biāo)單擊一下,按鈕的顏色會(huì)變淡,再單擊一下又會(huì)變亮,它是以顏色的的深淺來提醒它的toggle的。菜單欄中的一個(gè)選項(xiàng),一般是用trigger來發(fā)射信號(hào)。2報(bào)錯(cuò)出現(xiàn)“cannot find file main.pro”,原因是QT所使用的工程,目錄樹中出現(xiàn)漢字,空格等。題目2基本C/S模式的通信實(shí)驗(yàn)1、設(shè)計(jì)內(nèi)容基本C/S模式的通信實(shí)驗(yàn)編寫程序?qū)崿F(xiàn)一個(gè)基于UDP 模式的通信程序和一個(gè)基于TCP 模式的通信程序。基本要求:能輸入計(jì)算機(jī)的IP地址和端口號(hào),能輸入、發(fā)送文本信息
11、和顯示接受的文本信息。2、設(shè)計(jì)分析論述及程序?qū)崿F(xiàn)流程框圖一、基于UDP模式在UDP方式下,它是一個(gè)不可靠的,面向數(shù)據(jù)報(bào)的無連接協(xié)議。客戶端并不與服務(wù)器建立連接,它只負(fù)責(zé)調(diào)用發(fā)送函數(shù)向服務(wù)器發(fā)出數(shù)據(jù)報(bào)。同樣,服務(wù)器也不從客戶端接收連接,只負(fù)責(zé)調(diào)用接收函數(shù),等待來自某客戶端的數(shù)據(jù)到達(dá)。Qt中通過QupSocket類實(shí)現(xiàn)UDP協(xié)議的編程。Socket簡(jiǎn)單地說,就是一個(gè)IP 地址加一個(gè)port端口。因?yàn)橐獋鬏敂?shù)據(jù),就要知道往哪個(gè)機(jī)子上傳送,而IP 地址確定了一臺(tái)主機(jī),但是這臺(tái)機(jī)子上可能運(yùn)行著各種各樣的網(wǎng)絡(luò)程序,這時(shí)就要使用一個(gè)端口來指定UDP 程序。所以說,Socket 指明了數(shù)據(jù)報(bào)傳輸?shù)穆窂?。編寫?/p>
12、個(gè)程序,一個(gè)用來發(fā)送數(shù)據(jù)報(bào),叫做客戶端;另一個(gè)用來接收數(shù)據(jù)報(bào),叫做服務(wù)器端,均應(yīng)用UDP 協(xié)議。這樣也就構(gòu)成了所謂的C/S(客戶端/服務(wù)器)編程模型。首先做服務(wù)器端。先在頭文件udpclient.h中聲明需要的各種控件,完成對(duì)應(yīng)源代碼,從而先形成一個(gè)服務(wù)器的界面。然后在頭文件udpclient.h中添加需要的槽函數(shù),在源文件udpserver.cpp中添加聲明,設(shè)置好端口參數(shù)(本程序設(shè)置為5555)并且創(chuàng)建QUdpSocket,使程序能夠定向發(fā)送廣播地址。接下來做客戶端。同樣先在頭文件udpclient.h中聲明需要的各種控件,完成對(duì)應(yīng)源代碼,從而形成一個(gè)客戶端的界面。然后在構(gòu)造函數(shù)中設(shè)置相對(duì)
13、應(yīng)的端口號(hào)參數(shù)(5555),定義CloseBtnClicked()和dataReceived()函數(shù),最后實(shí)現(xiàn)客戶端的功能。圖2-1 UDP協(xié)議工作原理圖2-2 UDP客戶端與服務(wù)器之間的交互方式二、基于TCP模式1.圖2-3 TCP協(xié)議工作原理2. 圖2-4 TCP客戶端與服務(wù)器間的交互時(shí)序3.圖2-5 TCP文件傳輸結(jié)構(gòu)3、關(guān)鍵實(shí)現(xiàn)代碼及注解一、基于UDP模式服務(wù)器端:1.在UdpServer.pro中添加:QT += network2.在頭文件udpserver.h中添加需要的槽函數(shù):#include /Line11.12聲明,為了在Line21-32添加槽函數(shù)#include publ
14、ic slots: void StartBtnClicked(); void timeout();private: QLabel *TimerLabel; QLineEdit *TextLineEdit; QPushButton *StartBtn; QVBoxLayout *mainLayout; int port; bool isStarted; QUdpSocket *udpSocket;QTimer *timer;3.在udpserver.cpp的槽函數(shù)中添加如下代碼:connect(StartBtn,SIGNAL(clicked(),this,SLOT(StartBtnClicked
15、(); port =6665;/設(shè)置UDP的端口號(hào)參數(shù),服務(wù)器定時(shí)向此端口發(fā)送廣播消息 isStarted=false; udpSocket = new QUdpSocket(this); timer = new QTimer(this);/創(chuàng)建一個(gè)QUdpSocket connect(timer,SIGNAL(timeout(),this,SLOT(timeout();/定時(shí)發(fā)送廣播信息4. StartBtnClicked()函數(shù)的具體代碼:void UdpServer:StartBtnClicked()/“開始”按鈕函數(shù)的設(shè)定 if(!isStarted) StartBtn-setText
16、(u8停止); timer-start(1000); isStarted =true; else StartBtn-setText(u8開始); isStarted = false; timer-stop(); 5.timeout()函數(shù)完成了向端口發(fā)送廣播消息的功能:void UdpServer:timeout()/完成向端口發(fā)送廣播信息的功能 QString msg = TextLineEdit-text(); int length=0; if(msg=) return; if(length=udpSocket-writeDatagram(msg.toLatin1(),msg.length
17、(),QHostAddress:Broadcast,port)!=msg.length() return; /QHostAddress:Broadcast指定向廣播地址發(fā)送客戶端:1.在UdpClient.pro中加入代碼:QT += network2.在udpclient.cpp的構(gòu)造函數(shù)中添加代碼:connect(CloseBtn,SIGNAL(clicked(),this,SLOT(CloseBtnClicked(); port =6665;/設(shè)置UDP的端口號(hào)參數(shù),指定在此端口上監(jiān)聽數(shù)據(jù) udpSocket = new QUdpSocket(this);/創(chuàng)建一個(gè)QUdpSocket
18、connect(udpSocket,SIGNAL(readyRead(),this,SLOT(dataReceived(); /連接QIODevice的readyRead()信號(hào)。QUdpSocket也是一個(gè)I/O設(shè)備,從QIODevice繼承而來,當(dāng)有數(shù)據(jù)到達(dá)I/O設(shè)備時(shí),發(fā)出readyRead()信號(hào) bool result=udpSocket-bind(port);/綁定到指定端口上 if(!result) QMessageBox:information(this,tr(error),tr(udp socket create error!); return;3.定義CloseBtnCli
19、cked()函數(shù):void UdpClient:CloseBtnClicked() close();4.定義dataReceived()函數(shù):void UdpClient:dataReceived()/響應(yīng)QUdpSocket的readyRead()信號(hào),一旦UdpSocket對(duì)象中有數(shù)據(jù)可讀時(shí),即通過readyDatagram()方法將數(shù)據(jù)讀出并顯示 while(udpSocket-hasPendingDatagrams()/判斷UdpSocket中是否有數(shù)據(jù)報(bào)可讀,hasPendingDatagrams()方法在至少有一個(gè)數(shù)據(jù)報(bào)可讀時(shí)返回true,否則返回false QByteArray
20、datagram;/Line47-50實(shí)現(xiàn)了讀取第一個(gè)數(shù)據(jù)報(bào),pendingDatagramSize()可以獲得第一個(gè)數(shù)據(jù)報(bào)長(zhǎng)度 datagram.resize(udpSocket-pendingDatagramSize(); udpSocket-readDatagram(datagram.data(),datagram.size(); QString msg=datagram.data(); ReceiveTextEdit-insertPlainText(msg);/顯示數(shù)據(jù)內(nèi)容 二、基于TCP模式服務(wù)器端:1.頭文件“tcpserver.h”中聲明了需要的各種控件,TcpServer繼承自
21、Qdialog,實(shí)現(xiàn)了服務(wù)器端的對(duì)話框顯示與控制。具體代碼如下2:#include #include #include #include #include #include #include server.hclass TcpServer : public QDialog Q_OBJECTpublic: TcpServer(QWidget *parent = 0,Qt:WindowFlags f=0); TcpServer();private: QListWidget *ContentListWidget; QLabel *PortLabel; QLineEdit *PortLineEdit;
22、 QPushButton *CreateBtn; QGridLayout *mainLayout; int port; Server *server;2.在源文件“tcpserver.cpp”中,TcpServer類的構(gòu)造函數(shù)主要實(shí)現(xiàn)窗體各控件的創(chuàng)建、布局等,其具體代碼如下:#include tcpserver.hTcpServer:TcpServer(QWidget *parent,Qt:WindowFlags f) : QDialog(parent,f) setWindowTitle(tr(TCP Server); ContentListWidget = new QListWidget;
23、PortLabel = new QLabel(u8端口:); PortLineEdit = new QLineEdit; CreateBtn = new QPushButton(u8創(chuàng)建聊天室); mainLayout = new QGridLayout(this); mainLayout-addWidget(ContentListWidget,0,0,1,2); mainLayout-addWidget(PortLabel,1,0); mainLayout-addWidget(PortLineEdit,1,1); mainLayout-addWidget(CreateBtn,2,0,1,2)
24、; port=5555; PortLineEdit-setText(QString:number(port); connect(CreateBtn,SIGNAL(clicked(),this,SLOT(slotCreateServer();3. 在工程“TcpServer.pro”中添加如下語(yǔ)句:QT += network4. 在工程“TcpServer.pro”中添加C+類文件“tcpclientsocket.h”及“tcpclientsocket.cpp”,TcpClientSocket繼承自QTcpSocket,創(chuàng)建一個(gè)TCP套接字,以便在服務(wù)器端實(shí)現(xiàn)與客戶端程序的通信。在源文件“tcp
25、clientsocket.cpp”中,構(gòu)造函數(shù)(TcpClientSocket)的內(nèi)容如下(它指定了信號(hào)與槽的連接關(guān)系):#include tcpclientsocket.hTcpClientSocket:TcpClientSocket(QObject *parent)/指定了信號(hào)與槽的連接關(guān)系 connect(this,SIGNAL(readyRead(),this,SLOT(dataReceived(); connect(this,SIGNAL(disconnected(),this,SLOT(slotDisconnected();/disconnected()信號(hào)在斷開連接時(shí)發(fā)出5. 在
26、源文件“tcpclientsocket.cpp”中,dataReceived()函數(shù)的具體代碼如下:void TcpClientSocket:dataReceived()/有數(shù)據(jù)到來時(shí),觸發(fā)dataReceived()函數(shù),從套接字中將有效數(shù)據(jù)取出,然后發(fā)出updateClients()信號(hào)。 while(bytesAvailable()0) int length = bytesAvailable(); char buf1024; read(buf,length); QString msg=buf; emit updateClients(msg,length);/updateClients()
27、信號(hào)是通知服務(wù)器向聊天室內(nèi)的所有成員廣播信息 6.在工程“TcpServer.pro”中添加C+類文件“server.h”及“server.cpp”,Server繼承自QTcpServer,實(shí)現(xiàn)一個(gè)TCP協(xié)議的服務(wù)器。利用QTcpServer,開發(fā)著可以監(jiān)聽到指定端口的TCP連接。其具體代碼如下:#include #include #include tcpclientsocket.h/包含TCP套接字class Server : public QTcpServer Q_OBJECT /添加宏(Q_OBJECT)是為了實(shí)現(xiàn)信號(hào)與槽的通信public: Server(QObject *parent
28、=0,int port=0); QList tcpClientSocketList;/用來保存與每一個(gè)客戶端連接的TcpClientSocketsignals: void updateServer(QString,int);public slots: void updateClients(QString,int); void slotDisconnected(int);protected: void incomingConnection(int socketDescriptor);7.在源文件“server.cpp”中,構(gòu)造函數(shù)(Server)的具體內(nèi)容如下:#include server.h
29、Server:Server(QObject *parent,int port) :QTcpServer(parent) listen(QHostAddress:Any,port);/在指定的端口對(duì)任意地址進(jìn)行監(jiān)聽8. 在源文件“server.cpp”中,當(dāng)出現(xiàn)一個(gè)新的連接時(shí),QTcpServer會(huì)立即觸發(fā)incomingConnection()函數(shù),參數(shù)socketDescriptor指定了連接的Socket描述符,其具體代碼如下:void Server:incomingConnection(int socketDescriptor)/出現(xiàn)一個(gè)新的連接時(shí),QTcpServer觸發(fā)incomin
30、gConnection()函數(shù) TcpClientSocket *tcpClientSocket=new TcpClientSocket(this);/創(chuàng)建一個(gè)新的TcpClientSocket與客戶端通信 connect(tcpClientSocket,SIGNAL(updateClients(QString,int),this,SLOT(updateClients(QString,int);/連接TcpClientSocket的updateClients信號(hào) connect(tcpClientSocket,SIGNAL(disconnected(int),this,SLOT(slotDis
31、connected(int);/連接TcpClientSocket的disconnected信號(hào) tcpClientSocket-setSocketDescriptor(socketDescriptor);/將新創(chuàng)建的TcpClientSocket的套接字描述符指定為參數(shù)socketDescriptor tcpClientSocketList.append(tcpClientSocket);/將tcpClientSocketList加入客戶端套接字列表以便管理9. 在源文件“server.cpp”中,updateClients()函數(shù)將任意客戶端發(fā)來的信息進(jìn)行廣播,保證聊天室的所有客戶均能看到
32、其他人的發(fā)言。其具體代碼如下:void Server:updateClients(QString msg,int length)/將任意客戶端發(fā)來的信息進(jìn)行廣播,保證聊天室的所有客戶均能看到其他人的發(fā)言 emit updateServer(msg,length); for(int i=0;iwrite(msg.toLatin1(),length)!=length) continue; 10. 在源文件“tcpserver.cpp”中,槽函數(shù)slotCreateServer()用于創(chuàng)建一個(gè)TCP服務(wù)器,具體內(nèi)容如下:void TcpServer:slotCreateServer()/創(chuàng)建一個(gè)TC
33、P服務(wù)器 server = new Server(this,port);/創(chuàng)建一個(gè)Server對(duì)象 connect(server,SIGNAL(updateServer(QString,int),this,SLOT(updateServer(QString,int);/將Server對(duì)象的updateServer()信號(hào)與相應(yīng)的槽函數(shù)進(jìn)行連接 CreateBtn-setEnabled(false);客戶端:1.源文件“tcpclient.cpp”的具體代碼如下:#include tcpclient.h#include #include TcpClient:TcpClient(QWidget *
34、parent,Qt:WindowFlags f) : QDialog(parent,f) setWindowTitle(tr(TCP Client); contentListWidget = new QListWidget; sendLineEdit = new QLineEdit; sendBtn = new QPushButton(u8發(fā)送); userNameLabel = new QLabel(u8用戶名:); userNameLineEdit = new QLineEdit; serverIPLabel = new QLabel(u8服務(wù)器地址:); serverIPLineEdit
35、 = new QLineEdit; portLabel = new QLabel(u8端口:); portLineEdit = new QLineEdit; enterBtn= new QPushButton(u8進(jìn)入聊天室); mainLayout = new QGridLayout(this); mainLayout-addWidget(contentListWidget,0,0,1,2); mainLayout-addWidget(sendLineEdit,1,0); mainLayout-addWidget(sendBtn,1,1); mainLayout-addWidget(user
36、NameLabel,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);2.在客戶端工程文件“TcpClient.pro”中添加如下語(yǔ)句:QT +=
37、network3.在源文件“tcpclient.cpp”的構(gòu)造函數(shù)中添加如下代碼:status = false; port = 5555; /隨意設(shè)置端口號(hào) portLineEdit-setText(QString:number(port); serverIP =new QHostAddress(); connect(enterBtn,SIGNAL(clicked(),this,SLOT(slotEnter(); connect(sendBtn,SIGNAL(clicked(),this,SLOT(slotSend(); sendBtn-setEnabled(false);以上代碼中,槽函數(shù)s
38、lotEnter()實(shí)現(xiàn)了進(jìn)入和離開聊天室的功能。具體代碼如下:void TcpClient:slotEnter()/實(shí)現(xiàn)了進(jìn)入和離開聊天室的功能 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(
39、User name error!); return; userName=userNameLineEdit-text(); tcpSocket = new QTcpSocket(this); connect(tcpSocket,SIGNAL(connected(),this,SLOT(slotConnected(); connect(tcpSocket,SIGNAL(disconnected(),this,SLOT(slotDisconnected(); connect(tcpSocket,SIGNAL(readyRead(),this,SLOT(dataReceived(); tcpSocke
40、t-connectToHost(*serverIP,port); status=true; else int length=0; QString msg=userName+tr(:Leave Chat Room); if(length=tcpSocket-write(msg.toLatin1(),msg.length()!=msg. length() return; tcpSocket-disconnectFromHost(); status=false; 4. 槽函數(shù)slotConnected():void TcpClient:slotConnected()/槽函數(shù)slotConnected
41、()為connected()信號(hào)的響應(yīng)槽,當(dāng)與服務(wù)器連接成功后,客戶端構(gòu)造一條進(jìn)入聊天室的消息,并通知服務(wù)器 sendBtn-setEnabled(true); enterBtn-setText(u8離開); int length=0; QString msg=userName+tr(:Enter Chat Room); if(length=tcpSocket-write(msg.toLatin1(),msg.length()!=msg.length() return; 5.源文件“tcpclient.cpp”中的dataReceived()函數(shù):void TcpClient:dataRece
42、ived()/有數(shù)據(jù)到來時(shí),觸發(fā)此函數(shù),從套接字中將有效數(shù)據(jù)取出并顯示 while(tcpSocket-bytesAvailable()0) QByteArray datagram; datagram.resize(tcpSocket-bytesAvailable(); tcpSocket-read(datagram.data(),datagram.size(); QString msg=datagram.data(); contentListWidget-addItem(msg.left(datagram.size(); 4、程序運(yùn)行測(cè)試與結(jié)果一、基于UDP模式圖2-6 服務(wù)器端窗口圖2-7
43、 客戶端窗口說明:打開服務(wù)器端口,輸入字符(最好是英文字符),同時(shí)打開客戶端。在服務(wù)器端點(diǎn)擊“開始”按鈕,便以時(shí)鐘間隔向客戶端發(fā)送輸入的字符,同時(shí)顯示在客戶端窗口上,直到點(diǎn)擊“停止”按鈕,才終止發(fā)送。二、基于TCP模式圖2-8服務(wù)器端窗口圖2-9 客戶端窗口說明: 操作方式類似于UDP。點(diǎn)擊發(fā)送即可進(jìn)行客戶端和服務(wù)器之間的對(duì)話。5、程序設(shè)計(jì)中遇到的問題及改進(jìn)思路1. 出現(xiàn)field m_createDate has incomplete type錯(cuò)誤。由于只在頭文件中加了class聲明,如class QDateTime,在cpp文件中也使用#include 將該類引入,但由于使用QDateTi
44、me m_createDate;方式為創(chuàng)建了QDateTime對(duì)象,但由于只是對(duì)QDateTime類進(jìn)行了聲明而隱藏了類的實(shí)現(xiàn),此時(shí)編譯時(shí)不知道QDateTime的完成實(shí)現(xiàn)所以無法創(chuàng)建QDateTime對(duì)象。解決方法是在頭文件中使用#include 方式替換class QDateTime。2出現(xiàn)“QApplication: No such file or directory”報(bào)錯(cuò)。則檢查工程文件中*.pro中是否有“QT += widgets”,若沒有,則需要在工程文件*.pro下增加一條:“QT += widgets”,則問題就可以解決了。3出現(xiàn)“error: tr was not decl
45、ared in this scope”,tr這個(gè)函數(shù)是QObject對(duì)象中的靜態(tài)成員函數(shù),因此使用的時(shí)候,如果不是用類來寫的話,就會(huì)報(bào)這個(gè)錯(cuò)誤,只需要在tr函數(shù)前加上“QObject:”,如:“QObject:tr(a button)”這樣既可。題目3簡(jiǎn)單的瀏覽器的實(shí)現(xiàn)1、設(shè)計(jì)內(nèi)容簡(jiǎn)單的瀏覽器的實(shí)現(xiàn):設(shè)計(jì)一個(gè)簡(jiǎn)單的瀏覽器?;疽螅涸诓藛雾?xiàng)或工具條實(shí)現(xiàn)打開一個(gè)新的網(wǎng)頁(yè)指定的功能。提高要求:在菜單項(xiàng)或工具條實(shí)現(xiàn)下述功能之一:清除自動(dòng)密碼歷史記錄。瀏覽器地址欄歷史地址的清除。清空臨時(shí)目錄。2、設(shè)計(jì)分析論述及程序?qū)崿F(xiàn)流程框圖Qt5開始,應(yīng)用層的編程使用QNetworkRequest、QNetwork
46、Reply和QNetworkAccessManager這幾個(gè)高層次的類。其中,網(wǎng)絡(luò)請(qǐng)求由QnetworkRequest類來表示,作為與請(qǐng)求有關(guān)的信息的統(tǒng)一容器,在創(chuàng)建請(qǐng)求對(duì)象時(shí)指定的URL決定了請(qǐng)求使用的協(xié)議,目前支持HTTP、FTP和本地文件URLs的上傳和下載;QnetworkAccessManager類用于協(xié)調(diào)網(wǎng)絡(luò)操作,每當(dāng)一個(gè)請(qǐng)求創(chuàng)建后,該類用來調(diào)度它,并發(fā)射信號(hào)來報(bào)告進(jìn)度;而對(duì)于網(wǎng)絡(luò)請(qǐng)求的應(yīng)答則使用QnetworkReply類表示,它會(huì)在請(qǐng)求被完成調(diào)度時(shí)由QnetworkAccessManager創(chuàng)建。新建Qt Gui應(yīng)用,名稱為“myHTTP”,類名為“MainWindow”。完成
47、后進(jìn)入設(shè)計(jì)模式,即打開ui界面設(shè)計(jì),向界面上拖入一個(gè)Text Browser窗口,然后在頭文件和源文件中加入相應(yīng)代碼。圖3-1 瀏覽器與服務(wù)器的連接過程圖3-2 ui界面的設(shè)計(jì)3、關(guān)鍵實(shí)現(xiàn)代碼及注解1.進(jìn)入“mainwindow.h”文件,首先添加類的前置聲明: class QNetworkReply; /Line5.6為類的前置聲明class QNetworkAccessManager;2.添加一個(gè)私有對(duì)象定義:QNetworkAccessManager *manager;3.添加一個(gè)私有槽的聲明:private slots:void replyFinished(QNetworkReply
48、*);/此私有槽聲明上面的私有對(duì)象4.在“mainwindow.cpp”文件中添加頭文件:#include 然后在構(gòu)造函數(shù)中添加如下代碼:manager = new QNetworkAccessManager(this);/首先創(chuàng)建一個(gè)QNetworkAccessManager類的實(shí)例,用來發(fā)送網(wǎng)絡(luò)請(qǐng)求和接收應(yīng)答 connect(manager,SIGNAL(finished(QNetworkReply*),this,SLOT(replyFinished(QNetworkReply*);/關(guān)聯(lián)管理器的finished()信號(hào)和自定義的槽,每當(dāng)網(wǎng)絡(luò)應(yīng)答結(jié)束時(shí)都會(huì)發(fā)射這個(gè)信號(hào)manager-get
49、(QNetworkRequest(QUrl(http:/);/使用get()函數(shù)發(fā)送一個(gè)網(wǎng)絡(luò)請(qǐng)求,請(qǐng)求使用QNetworkRequest類表示,get()函數(shù)返回一個(gè)QNetworkReply類對(duì)象5.添加槽的定義:void MainWindow:replyFinished(QNetworkReply *reply) QString all = reply-readAll(); ui-textBrowser-setText(all); reply-deleteLater(); 因?yàn)镼NetworkReply繼承自QIODevice類,所以可以像操作一般的I/O設(shè)備一樣操作該類。這里使用了rea
50、dAll()函數(shù)來讀取所有的應(yīng)答數(shù)據(jù)。在完成數(shù)據(jù)的讀取后,需要使用deleteLater()刪除reply對(duì)象。4、程序運(yùn)行測(cè)試與結(jié)果 先實(shí)現(xiàn)網(wǎng)頁(yè)上文字鏈接的顯示。如圖3-3.圖3-3然后查閱網(wǎng)上資料,完成完整的瀏覽器設(shè)計(jì)??梢暂斎刖W(wǎng)址瀏覽網(wǎng)頁(yè),可以將網(wǎng)頁(yè)添加到收藏夾,可以生成瀏覽歷史記錄。如圖3-4,3-5.圖3-4圖3-55、程序設(shè)計(jì)中遇到的問題及改進(jìn)思路1. 當(dāng)使用tr進(jìn)行語(yǔ)言國(guó)際化時(shí),有可能會(huì)出現(xiàn)錯(cuò)誤:error : tr was not declared in this scope。解決方法:在程序中加入#include,并使用QObject:tr();2. 編譯時(shí)遇到“No rul
51、e to make target xxx.cpp, needed by debug/xxx.o. Stop.”的問題,出現(xiàn)該問題的原因?yàn)?,?pro文件中包含了某.cpp文件和.h文件,但是在項(xiàng)目中可能因?yàn)樵撐募幢皇褂茫诒镜刂苯觿h掉了該文件,而.pro文件中還包含了這兩個(gè)文件的引用,此時(shí)編譯就會(huì)出現(xiàn)以上問題。解決辦法是在.pro文件中刪除“xxx.cpp”和“xxx.h”的引用即可。題目4利用smtp協(xié)議發(fā)送郵件1、設(shè)計(jì)內(nèi)容利用smtp協(xié)議發(fā)送郵件基本要求:能發(fā)送內(nèi)容為文本信息的郵件。提高要求:能發(fā)送帶有附件信息的郵件。2、設(shè)計(jì)分析論述及程序?qū)崿F(xiàn)流程框圖SMTP稱為簡(jiǎn)單郵件傳輸協(xié)議(Sim
52、ple Mail Transfer Protocal),目標(biāo)是向用戶提供高效、可靠的郵件傳輸。它的一個(gè)重要特點(diǎn)是它能夠在傳送中接力傳送郵件,即郵件可以通過不同網(wǎng)絡(luò)上的主機(jī)接力式傳送。通常它工作在兩種情況下:一是郵件從客戶機(jī)傳輸?shù)椒?wù)器;二是從某一個(gè)服務(wù)器傳輸?shù)搅硪粋€(gè)服務(wù)器。SMTP是一個(gè)請(qǐng)求/響應(yīng)協(xié)議,它監(jiān)聽25號(hào)端口,用于接收用戶的Mail請(qǐng)求,并與遠(yuǎn)端Mail服務(wù)器建立SMTP連接。SMTP通常有兩種工作模式。發(fā)送SMTP和接收SMTP。具體工作方式為:發(fā)送SMTP在接收到用戶的郵件請(qǐng)求后,判斷此郵件是否為本地郵件,若是直接投送到用戶的郵箱,否則向DNS查詢遠(yuǎn)端郵件服務(wù)器的MX記錄,并建立
53、與遠(yuǎn)端接收SMTP之間的一個(gè)雙向傳送通道,此后SMTP命令由發(fā)送SMTP發(fā)出,由接收SMTP接收,而應(yīng)答則反方向傳送。一旦傳送通道建立,SMTP發(fā)送者發(fā)送MAIL命令指明郵件發(fā)送者。如果SMTP接收者可以接收郵件則返回OK應(yīng)答。SMTP發(fā)送者再發(fā)出RCPT命令確認(rèn)郵件是否接收到。如果SMTP接收者接收,則返回OK應(yīng)答;如果不能接收到,則發(fā)出拒絕接收應(yīng)答(但不中止整個(gè)郵件操作),雙方將如此反復(fù)多次。當(dāng)接收者收到全部郵件后會(huì)接收到特別的序列,入伏哦接收者成功處理了郵件,則返回OK應(yīng)答。SMTP的連接和發(fā)送過程大致如下:(1)建立TCP連接;(2)客戶端發(fā)送HELO命令以標(biāo)識(shí)發(fā)件人自己的身份,然后客
54、戶端發(fā)送MAIL命令。服務(wù)器端正希望以O(shè)K作為響應(yīng),表明準(zhǔn)備接收;(3)客戶端發(fā)送RCPT命令,以標(biāo)識(shí)該電子郵件的計(jì)劃接收人,可以有多個(gè)RCPT行。服務(wù)器端則表示是否愿意為收件人接收郵件;(4)協(xié)商結(jié)束,發(fā)送郵件,用命令DATA發(fā)送;(5)以.表示結(jié)束輸入內(nèi)容一起發(fā)送出去;(6)結(jié)束此次發(fā)送,用QUIT命令退出。3、關(guān)鍵實(shí)現(xiàn)代碼及注解1.在SMTP.pro文件中加入如下代碼,依次讀取工程目錄中其他文件夾的內(nèi)容:SOURCES += src/emailaddress.cpp src/mimeattachment.cpp src/mimefile.cpp src/mimehtml.cpp src/mimeinlinefile.cpp src/mimemessage.cpp src/mimepart.cpp src/mimetext.cpp src/smtpclient.cpp src/quotedprintable.cpp src/mimemultipart.cpp src/mimecontentformatter.cpp src/main.cpp src/sendemail.cppHEADERS += src/emailaddress.h src/mimeattachment.h src/mim
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 道路運(yùn)輸組織 客運(yùn)設(shè)施現(xiàn)代化PPT課件
- 應(yīng)用程序的結(jié)構(gòu)工程師課件
- 正弦穩(wěn)態(tài)分析
- 汽車照明與信號(hào)系統(tǒng)1
- 攝像頭的工作原理PPT課件
- 高中英語(yǔ)課程標(biāo)準(zhǔn)簡(jiǎn)介
- 目標(biāo)管理實(shí)務(wù)布衣公子作品版teliss課件
- 高中英語(yǔ)新課程通識(shí)培訓(xùn)校本研修
- (河南專版)九年級(jí)化學(xué)上冊(cè) 第五單元 化學(xué)方程式 課題1 第2課時(shí) 化學(xué)方程式(增分課練)習(xí)題課件 (新版)新人教版
- XXXX年淥口三級(jí)聯(lián)儲(chǔ)推介會(huì)講稿
- 131平方根(教育精品)
- 一年級(jí)《漢語(yǔ)拼音復(fù)習(xí)三》課件(教育精品)
- 為品牌戰(zhàn)略奠定基礎(chǔ)
- 化妝整體服務(wù)方案課件
- 同分異構(gòu)體的書寫課件