日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计算机网络课程设计之网络聊天程序的设计与实现

發(fā)布時間:2025/3/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计算机网络课程设计之网络聊天程序的设计与实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

計算機網(wǎng)絡(luò)課程設(shè)計開始,要求用C/C++,而且有些題目還要有圖形界面,因此決定用Qt寫圖形界面,同時決定用一個程序完成所有的實驗設(shè)計。

白嫖容易,創(chuàng)作不易,本文原創(chuàng),轉(zhuǎn)載請注明!!!
源碼和可運行程序:
鏈接:https://pan.baidu.com/s/1A9KctmpP2JJgyW2wLrehIg
提取碼:Lin2

計算機網(wǎng)絡(luò)課程設(shè)計:
計算機網(wǎng)絡(luò)課程設(shè)計之網(wǎng)絡(luò)聊天程序的設(shè)計與實現(xiàn)
計算機網(wǎng)絡(luò)課程設(shè)計之Tracert與Ping程序設(shè)計與實現(xiàn)
計算機網(wǎng)絡(luò)課程設(shè)計之基于 IP 多播的網(wǎng)絡(luò)會議程序
計算機網(wǎng)絡(luò)課程設(shè)計之網(wǎng)絡(luò)嗅探器的設(shè)計與實現(xiàn)
計算機網(wǎng)絡(luò)課程設(shè)計之電子郵件客戶端程序設(shè)計與實現(xiàn)
計算機網(wǎng)絡(luò)課程設(shè)計之TELNET 終端設(shè)計與實現(xiàn)
計算機網(wǎng)絡(luò)課程設(shè)計之網(wǎng)絡(luò)代理服務器的設(shè)計與實現(xiàn)
計算機網(wǎng)絡(luò)課程設(shè)計之簡單 Web Server 程序的設(shè)計與實現(xiàn)

Qt入門系列:
Qt學習之C++基礎(chǔ)
Qt學習之Qt安裝
Qt學習之Qt基礎(chǔ)入門(上)
Qt學習之Qt基礎(chǔ)入門(中)
Qt學習之Qt基礎(chǔ)入門(下)

創(chuàng)作不易,整個課程設(shè)計程序3000多行代碼,所有實驗都寫在了一個程序中,時間有限,能力不足,轉(zhuǎn)載望注明!!!
本文鏈接
個人博客:https://ronglin.fun/archives/264
PDF鏈接:見博客網(wǎng)站
CSDN: https://blog.csdn.net/RongLin02/article/details/122509928

實驗題目

網(wǎng)絡(luò)聊天程序的設(shè)計與實現(xiàn)

實驗目的

了解 Socket 通信的原理,在此基礎(chǔ)上編寫一個聊天程序。

總體設(shè)計

(含背景知識或基本原理與算法、或模塊介紹、設(shè)計步驟等)
本次設(shè)計客戶端用了Qt,Qt的一個很鮮明的特色就是可以使用槽函數(shù)異步處理數(shù)據(jù)。
服務器端用了Java,因為要用到多線程處理每一個客戶端,同時用到了很多阻塞式方法,Java的庫中對于多線程的處理十分方便,因此服務器用Java書寫。

客戶端

在Qt中創(chuàng)建一個TCP連接十分簡單
參考博客:QT5實現(xiàn)簡單的TCP通信
首先使用QT的網(wǎng)絡(luò)套接字需要.pro文件中加入一句:

QT += network

客戶端的代碼比服務器稍簡單,總的來說,使用QT中的QTcpSocket類與服務器進行通信只需要以下5步:

  • 創(chuàng)建QTcpSocket套接字對象
  • QTcpSocket* socket = new QTcpSocket();
  • 使用這個對象連接服務器
  • socket->connectToHost(IP, port);
  • 使用write函數(shù)向服務器發(fā)送數(shù)據(jù)
  • int result = socket->write(data);
  • 當socket接收緩沖區(qū)有新數(shù)據(jù)到來時,會發(fā)出readRead()信號,因此為該信號添加槽函數(shù)以讀取數(shù)據(jù)
  • QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);void MainWindow::socket_Read_Data() {QByteArray buffer;//讀取緩沖區(qū)數(shù)據(jù)buffer = socket->readAll(); }
  • 斷開與服務器的連接
    關(guān)于close()和disconnectFromHost()的區(qū)別,可以按F1看幫助
  • socket->disconnectFromHost(); //socket->close()

    服務器

    雖然服務器端用的是Java寫的,但是還是提一下Qt中如何創(chuàng)建服務器

    Qt TCP服務器

    服務器除了使用到了QTcpSocket類,還需要用到QTcpSever類。即便如此,也只是比客戶端復雜一點點,用到了6個步驟:

  • 創(chuàng)建QTcpSever對象
  • QTcpSocket server = new QTcpServer();
  • 偵聽一個端口,使得客戶端可以使用這個端口訪問服務器
    這里的第一個參數(shù)是QHostAddress,在Qt的assistant(幫助文檔)有詳細的說明
  • server->listen(QHostAddress::Any, port);
  • 當服務器被客戶端訪問時,會發(fā)出newConnection()信號,因此為該信號添加槽函數(shù),并用一個QTcpSocket對象接受客戶端訪問
  • connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect); void MainWindow::server_New_Connect() {//獲取客戶端連接socket = server->nextPendingConnection(); }
  • 使用socket的write函數(shù)向客戶端發(fā)送數(shù)據(jù)
  • int result = socket->write(data);
  • 當socket接收緩沖區(qū)有新數(shù)據(jù)到來時,會發(fā)出readRead()信號,因此為該信號添加槽函數(shù)以讀取數(shù)據(jù)
  • QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);void MainWindow::socket_Read_Data() {QByteArray buffer;//讀取緩沖區(qū)數(shù)據(jù)buffer = socket->readAll(); }
  • 取消偵聽
  • server->close();

    Qt異步處理數(shù)據(jù)用起來很方便,因為connect函數(shù)的存在,程序不用阻塞,可以等待槽函數(shù)的觸發(fā)。

    Java TCP服務器

    接下來說明Java如何創(chuàng)建一個TCP服務器
    參考博客:TCP通信的Java實現(xiàn)

  • 先創(chuàng)建一個ServerSocket類
  • 調(diào)用accept()方法獲取連接,此方法阻塞式方法
  • 獲取客戶端的輸入流,來讀客戶端數(shù)據(jù)
  • 獲取客戶端的輸出流,來向客戶端寫數(shù)據(jù)
  • 關(guān)閉所有對象
    代碼如下
  • import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket;public class Server {public static void main(String[] args) {//1. 創(chuàng)建服務器ServerSocket對象try {ServerSocket serverSocket = new ServerSocket(6666);//2. 獲取客戶端請求對象SocketSocket socket = serverSocket.accept();//3. 獲取字節(jié)輸入流對象InputStream inputStream = socket.getInputStream();//4. 讀取客戶端數(shù)據(jù)byte[] bytes = new byte[1024];int len = inputStream.read(bytes);System.out.println(new String(bytes,0,len));//5. 獲取字節(jié)輸出流對象OutputStream outputStream = socket.getOutputStream();//6. 向客戶端回寫數(shù)據(jù)outputStream.write("I am OK.".getBytes());//7. 釋放資源socket.close();serverSocket.close();} catch (IOException e) {e.printStackTrace();}} }

    詳細設(shè)計

    (含主要的數(shù)據(jù)結(jié)構(gòu)、程序流程圖、關(guān)鍵代碼等)

    數(shù)據(jù)格式

    首先是數(shù)據(jù)的數(shù)據(jù)格式,這里我設(shè)置了一個Message類,格式如下:

    TYPE: Information FROM: 11809 TO: 11810 TIME: 2022-01-05 17:18:49 CONTENT: test測試

    一共是5項數(shù)據(jù):

  • TYPE,表示數(shù)據(jù)的類型,類型一共有3種,一個是Heartbeat,表示心跳,心跳類的數(shù)據(jù)包只有一個Type類型的數(shù),其余都是0或者null,第二種是UserList,表示用戶列表,當有客戶端連入TCP服務器或者與其斷開的時候,會廣播發(fā)送一次UserList數(shù)據(jù)包,用來告訴所有客戶端更新用戶列表。最后一個是Information數(shù)據(jù)包,用來封裝消息。
  • FROM,在Information中表示數(shù)據(jù)的發(fā)送者
  • TO,在Information中表示數(shù)據(jù)的接收者,TCP服務器通過此來把數(shù)據(jù)發(fā)送給相應的TCPClient
  • TIME,時間,注意雖然發(fā)送者在發(fā)送的時候會填入一個時間到Information類數(shù)據(jù)包中,但是當數(shù)據(jù)到達服務器時,服務器會以本身的時間來更新這部分,以防客戶端本身的時間錯誤
  • CONTENT,表示內(nèi)容,即正文部分。
  • 服務器

    如果要實現(xiàn)聊天室,首先要先設(shè)計一個服務器,服務器的設(shè)計主要是Java多線程實現(xiàn)
    下面簡單說明一下設(shè)計過程

    一共有3類線程:

  • 第一類線程是在Main中的一個while(true),主要是向服務器中所有連接的客戶端發(fā)送心跳包,每500ms發(fā)送一個心跳包,如果發(fā)送失敗則說明客戶端已經(jīng)斷開,然后廣播一個UserList類型的數(shù)據(jù),來告訴客戶端更新列表。
  • 第二類線程是TCPServer線程,該線程的主要作用就是用來處理阻塞的accept()方法,當連接成功一個客戶端之后,將其添加到一個維護的ArrayList,然后再次while(true)阻塞accept()方法。
  • 第三類線程就是用來處理所有的客戶端的數(shù)據(jù),主要是處理阻塞的read()方法,用來監(jiān)聽客戶端的輸入。
  • 同時每一個客戶端的標識是用他們本身的本地Port數(shù)據(jù)來標識。

    客戶端


    界面如上,當點擊登錄的時候,socket開始連接,ip地址為自行寫死的"127.0.0.1"端口也是寫死的"60001",然后登錄之后收到來自服務器的UserList類型的數(shù)據(jù)包,然后更新自己的在線用戶欄目,復位就是清0一個計數(shù)變量,清空按鈕是清空上下的textEdit控件,啟動新進程是為了調(diào)試,主要是用來啟動一個新的子進程,發(fā)送按鈕的邏輯是先清空發(fā)送欄,然后調(diào)用write()方法,把數(shù)據(jù)打包成Message格式,然后發(fā)送給服務器。
    需要注意的是,要時刻注意判定是否在登錄的狀態(tài)下。

    實驗結(jié)果與分析

    下面展示一下過程

    可以看到連接成功,然后進行數(shù)據(jù)交換

    可以看到數(shù)據(jù)發(fā)送成功,同時在服務器端也能獲得數(shù)據(jù)
    當?shù)诙€客戶端斷開:

    當?shù)诙€斷開的時候,可以在服務器端看到14760已經(jīng)斷開,同時第一個客戶端可以看到14760已經(jīng)斷開了。

    小結(jié)與心得體會

    因為本實驗用的是Qt和Java已經(jīng)封裝好的TCP庫,所以用起來很方便,因為以前已經(jīng)有TCP服務開發(fā)經(jīng)驗所以本實驗開發(fā)比較簡單。
    個人覺得本次設(shè)計亮點在于設(shè)計Message類型和添加了心跳包。
    =w=

    總結(jié)

    以上是生活随笔為你收集整理的计算机网络课程设计之网络聊天程序的设计与实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。