1. 程式人生 > >聊天程序(基於Socket、Thread)

聊天程序(基於Socket、Thread)

客戶端信息 -- 聊天程序 soc 數組 net 運行 人的 圖解

聊天程序簡述


1、目的:主要是為了闡述Socket,以及應用多線程,本文側重Socket相關網路編程的闡述。如果您對多線程不了解,大家可以看下我的上一篇博文淺解多線程 。

2、功能:此聊天程序功能實現了服務端跟多個客戶端之間的聊天,可以群發消息,選擇ip發消息,客戶端向服務端發送文件。 (例子為WinForm應用程序)


Socket,端口,Tcp,UDP。 概念


1、Socket還被稱作“套接字”,應用程序通常通過套接字向網絡發送請求或者應答網絡請求。根據連接啟動的方式以及本地套接字要連接的目標,套接字之間的連接過程可以分為三個步驟:服務器監聽,客戶端請求,連接確認。

2、端口:可以認為是計算機與外界通訊交流的出口。

3、Tcp: TCP是一種面向連接(連接導向)的、可靠的、基於字節流的運輸層通信協議。UDP是另一個重要的傳輸協議。

4、UDP:用戶數據報協議,是一種無連接的傳輸層協議,提供面向事務的簡單不可靠信息傳送服務。


理解Socket,端口,Tcp,UDP


1、ip跟端口的作用:例如,你用QQ跟好友聊天,首先QQ要知根據好友所在電腦的IP地址發送信息,ip地址能確定好友的所在的電腦,但是不知道好友電腦上的QQ應用程序是哪一個,這就需要QQ提供一個端口號來確定你發過來的信息是QQ接受的數據。這樣就簡單的闡述了Ip跟端口的作用。

2、Tcp,Udp作用以及差異:首先要說的是,這是兩種網路協議,他們的差別就是TCP協議中包含了專門的傳遞保證機制,當數據接收方收到發送方傳來的信息時,會自動向發送方發出確認消息;發送方只有在接收到該確認消息之後才繼續傳送其它信息,否則將一直等待直到收到確認信息為止。與TCP不同,UDP協議並不提供數據傳送的保證機制。如果在從發送方到接收方的傳遞過程中出現數據報的丟失,協議本身並不能做出任何檢測或提示。我們.net程序員一般的應用程序用的都是Tcp協議。但是Tcp協議的執行速度,效率不及Udp快。看別人的博客感覺圖解這兩個協議,顯得更直觀點。上圖:

技術分享

3、Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把復雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數據,以符合指定的協議。出自同一篇博客的圖。

技術分享

4、到這裏如果你對Socket,還不是很清楚透徹,那麽在接下來的聊天程序代碼中,我還會一點點的闡述。


創建服務端監聽功能———聊天程序(Socket、Thread)


服務端監聽服務是創建一個Socket等待接收客戶端的信息。這個需要綁定服務端的Ip、端口號,以便於客戶端發送請求的時候找準確服務端聊天程序的具體位置。此外這個Socket還需要設置監聽序列的大小,告知應用程序一次性最多處理客戶端發來信息的多少。然後創建一個接收客戶端通信的Socket,等待客戶段發來的信息。

技術分享View Code

問題1:代碼中的Socket accSck = sck.Accept();這個Socket是讓上一個綁定服務端ip端口號的Socket一直處於等待接受客戶端發送信息的狀態,所以一直占用應用程序一直默認開啟的Ui線程,致使點擊開啟服務監聽後,界面無響應。

解決辦法:使用多線程,我們在這裏寫一個自己的線程讓這裏的監聽服務,寫在自己的線程裏面。修改代碼如下:

技術分享View Code

問題2:代碼中sck.Listen(10);設置監聽序列,這裏設置為10是不是,服務端只能處理10個客戶段的請求呢。

答:不是的這裏設置的是一次性只能處理10個,如果還有更多就在後面排隊,等待這10個處理完成,接下來在處理排著對的信息。

開啟服務監聽看一下我們的聊天界面:

技術分享

然後我們再做一個客戶端,鏈接到服務端。


創建客戶端鏈接服務端的Socket———聊天程序(Socket、Thread)


如果鏈接服務端的聊天程序則需要知道服務端的Ip地址,端口號。

技術分享View Code

然後點擊連接服務,查看我們的聊天界面。(首先先打開服務端應用程序,點擊開啟監聽,然後打開客戶端應用程序,點擊鏈接服務)

技術分享

鏈接成功後,下一步,我們就開始我們的聊天信息接收發送了。


服務端向客戶端發送信息,客戶端接受信息———聊天程序(Socket、Thread)


1、這裏我們發送消息是通過Tcp協議以 字節數組的類型形式發送,所以在發送之前我們需要把要發送,接收的數據做一個轉換為字節數組的類型。

2、客戶端通過創建的鏈接服務端的Socket的Receive方法接收消息,服務端通過創建的接受客戶端信息的Socket的Send方法發送消息。

服務端代碼:

技術分享View Code

客戶端代碼:

技術分享View Code

啟動服務端應用程序,點擊啟動服務監聽,啟動客戶端應用程序,點擊連接服務,然後在消息框內輸入消息,點擊發送。運行效果如下。


技術分享

接下來做客戶端向服務端發送消息:


客戶端向服務端發送信息(文件,字符串),客戶端接受信息———聊天程序(Socket、Thread)


1、這裏我們發送不僅只有字符串還有文件。他們都是一字節數組的類型發送出去,區別字符串和文件的思想是:把字節數組的第一個值設置為0跟1,用來區分。

2、這裏發送的文件接受的時候,重命名,還要為他寫上後綴名。沒有深入寫。

3、這裏客戶端連接服務端的成功後,把客戶端的ip端口號,寫入list列表中,同時也存入Dictionary<string, Socket> socketDir集合中,便於服務端與多個客戶端連接時,選擇發送信息。同時也避免了,不知道發送給哪個客戶端數據。

客戶端代碼:

技術分享View Code

服務端代碼:

技術分享View Code

啟動服務端應用程序,點擊啟動服務監聽,可以同時啟動多個客戶端應用程序,都要先點擊連接服務,然後在消息框內輸入消息,也可以選取文件,點擊發送。運行效果如下。


技術分享


總結:剩余一個群發,我沒寫上去,相信你如果看明白了上面我所寫的的話,這個群發,就so easy了。再次友情提醒一下,如果你不懂多線程,我的上一篇博客就是對他的淺解 。鏈接地址------->>“ 淺解多線程 ” 。

聊天程序(基於Socket、Thread)