C# 簡單的聊天大廳功能及原始碼(socket通訊)
一、前言起因
最近突然對socket通訊產生了興趣。於是簡單的研究了一下,下面將研究的東西用最簡單的大白話寫出來與大家分享下。比較淺顯,大神就別浪費時間看下面的內容了。
二、簡單介紹
socket:插座、插孔,這裡代表一種使用tcp或udp協議的簡單雙向通訊連線(即“”套接字“”,我個人就理解為私人固定電話與電話公司。下方文字為專業描述,括號裡的用固話和電話公司來比喻描述,可能不太準確望大神指教。)。主要包含客戶端和服務端,其最簡單的應用就是用於客戶端跟服務端進行通訊。
服務端(電話公司):先初始化Socket(建立公司),為其繫結IP和埠以便客戶端連線(bind,釋出電話公司聯絡方式),同時對其進行實時監聽(listen,等待家用電話辦理業務或來電諮詢),呼叫阻塞等待客戶端連線或發來訊息(accept,安排好客服)。
客戶端(家用固話):先初始化Socket(購買電話機),然後連線到伺服器(connect,去電話公司開戶,辦理電話線),同時服務端會給客戶端分配好連線埠(電話公司給家用固話分配電話號)。當然,客戶端也可以主動繫結未被佔用的埠(主動申請挑選靚號),但是並不推薦(辦理麻煩,同時可能辦理的號碼已經有人在用了)。
雙方通訊(溝通過程):如果連線伺服器成功(固話辦理成功,並分配好了電話號),客戶端則可以向服務端傳送資料,服務端同時也可以對接收到的內容進行處理並返回給客戶端(固話跟電話公司進行諮詢溝通),完成所有需要的操作後(所有諮詢溝通完畢),關閉連線完成通訊(結束通話電話)。如果連線未成功(辦理固話失敗了),則會引發連線異常(光買了電話,但是沒有電話線。。。)。
三、多人聊天大廳擴充套件思路
上述的連線過程為服務端與客戶端一對一來進行的。那我們有沒有什麼辦法可以多人一起進行聊天呢。當然是可以的,辦法很簡單,就是在服務端做一個訊息分發功能(電話公司的公告或廣播)。當有很多客戶端連線進來時(很多電話同時連線在電話公司中),一個客戶端給服務端傳送了訊息(甲用電話給電話公司留了言),那麼服務端則利用分發功能,將該客戶端發來的訊息同時分發給其他連線在服務端的客戶端(客戶公司將甲電話的留言,迴圈傳送給當時線上的乙電話、丙電話……)。那麼問題又來了,服務端如何儲存所有連線的客戶端資訊呢(電話公司如何儲存客戶資訊)。其實也很簡單,建立一個客戶端socket列表(電話公司的客戶資訊檔案),每當一個客戶端跟服務端連線成功時,服務端就主動的將客戶端socket儲存進列表(新使用者新增入檔案),當客戶端斷開時,在將其從列表中移除就即可(拆機的使用者從檔案中刪除)。以上就是這個demo所實現的思想,可能舉例不太準確,但就是個輔助理解的東西。望大家勿怪、勿噴。
四、核心方法程式碼
/// <summary>
/// 廣播資訊
/// </summary>
/// <param name="useStr">傳入收到的傳輸的內容</param>
/// <param name="obj">傳送資訊的客戶</param>
/// <param name="isSendSelf">是否推送給自己</param>
/// <param name="isServerSelf">是否為伺服器推送</param>
/// <returns>返回處理後的廣播訊息文字</returns>
private string Broadcast(string userStr, object obj,bool isSendSelf,bool isServerSelf)
{
Socket clientSend = obj as Socket; //當前傳送資訊的客戶
string rtnMessage = "";
try
{
foreach (Socket client in userList)
{
if (!isSendSelf) //不推送自己
{
if (client != clientSend)//將資訊廣播給其他使用者
{
if (!isServerSelf) //非伺服器推送
{
rtnMessage = IPToAddress(clientSend) + ":" + userStr;
client.Send(Encoding.Default.GetBytes(rtnMessage));
}
else //伺服器不推送伺服器IP和埠,只推送“伺服器”
{
rtnMessage = "【伺服器】:" + userStr;
client.Send(Encoding.Default.GetBytes(rtnMessage));
}
}
}
else //推送自己
{
if (!isServerSelf)//非伺服器推送
{
rtnMessage = IPToAddress(clientSend) + ":" + userStr;
client.Send(Encoding.Default.GetBytes(rtnMessage));
}
else //伺服器不推送伺服器IP和埠,只推送“伺服器”
{
rtnMessage = "【伺服器】:" + userStr;
client.Send(Encoding.Default.GetBytes(rtnMessage));
}
}
}
}
catch (Exception e)
{
userList.Remove(clientSend); //移除退出客戶
//Thread.CurrentThread.Abort();//退出時掐死執行緒,不然遞迴反彈
}
return rtnMessage;
}
/// <summary>
/// 監聽連線
/// </summary>
private void Accept()
{
//接受連線
Socket clientSocket = socketSevice.Accept();
userList.Add(clientSocket); //將連線的客戶端存入列表
string clientMess = "【伺服器】(" + DateTime.Now.ToString("HH:mm:ss")+")分配給您的埠為:(" + (clientSocket.RemoteEndPoint as IPEndPoint).Port.ToString() + ")"; //拼接分配埠號字串
clientSocket.Send(Encoding.Default.GetBytes(clientMess)); //將分配資訊反饋給連線的客戶端
string mess = IPToAddress(clientSocket) + ":連線進來了"; //廣播登入資訊的客戶端
Console.WriteLine(mess); //同步在服務端控制檯顯示
Broadcast(mess, clientSocket, false,true); //服務端廣播,客戶端連線訊息(不廣播給自己)
Thread RecvThread = new Thread(ReceMessage); //將接收客戶端訊息加入程式
RecvThread.IsBackground = true;
RecvThread.Start(clientSocket);
Accept();//遞迴
}
五、截圖
六、原始碼包
下載地址:https://download.csdn.net/download/fwl562213140/12948324
說明:
一、伺服器預設地址為:192.168.15.139,埠為:8888 。如需修改,可在服務端原始碼頂端的屬性中進行修改。
二、客戶端開啟後,預設為服務端連線地址賦值。如需修改,可在客戶端原始碼頂端的屬性中進行修改。
三、客戶端連線後,服務端自動將分配給客戶端的埠號返回客戶端。客戶端解析後新增到標題欄。(該處根據需要,可以自行修改為返回IP地址等連線資訊)
四、該demo由於只是為了實現簡單的聊天大廳功能,所以未考慮粘包的情況。如果需要考慮請自行新增。參考地址:https://blog.csdn.net/weixin_30379911/article/details/97265907
五、開發環境為VS2015,服務端使用控制檯,客戶端使用Winform進行編寫
六、本demo包中包含服務端、客戶端的開發原始碼以及生成後的可執行檔案。
七、轉載說明
碼字不易,轉載望留痕。
原文出處:https://blog.csdn.net/fwl562213140/article/details/109133059
相關文章
- c#實現最簡單的socket通訊C#
- 簡單的Socket通訊
- socket 完成簡單的通訊
- C# 如何實現簡單的Socket通訊(附示例)C#
- C#網路程式設計-簡單的通訊原始碼C#程式設計原始碼
- Java的Socket通訊簡單例項Java單例
- C# 通過socket實現UDP 通訊C#UDP
- C#實現聯通簡訊Sgip協議程式原始碼C#協議原始碼
- Socket最簡單的客戶端與服務端通訊-Java客戶端服務端Java
- 使用Scala模擬簡單的RPC通訊,Socket程式設計RPC程式設計
- Linux網路程式設計之socket簡單通訊--客戶端程式碼Linux程式設計客戶端
- socket通訊
- socket通訊的建立
- php的socket通訊PHP
- unix socket通訊
- Linux網路程式設計之socket簡單通訊TCP--服務端程式碼Linux程式設計TCP服務端
- C# 實現socket通訊程式(伺服器端)C#伺服器
- 簡單聊一聊Vuex的原理Vue
- 網路通訊2:TCP簡單通訊TCP
- 程式間通訊(Socket)
- socket.IO通訊
- Android Socket 通訊Android
- 【Python】socket通訊Python
- 簡單通訊錄的實現
- 簡單聊一聊FutureTask的實現
- 簡單區分WiFi通訊和WLAN通訊WiFi
- 簡單聊一聊ThreadPoolExecutorthread
- 簡單聊一聊Javascript中的模組化JavaScript
- PHP socket 的簡單理解PHP
- 清晰易懂TCP通訊原理解析(附demo、簡易TCP通訊庫原始碼、解決沾包問題等)C#版TCP原始碼C#
- SwiftNIO初探-簡單UDP通訊SwiftUDP
- smack和openfire通訊的簡單例子Mac單例
- 簡單的區域網內通訊
- 一段最簡單的使用socket.io進行伺服器和客戶端通訊的例子程式碼伺服器客戶端
- socket.io通訊原理
- Android TCP socket通訊AndroidTCP
- Socket套接字通訊原理
- 輕量級C#網路通訊元件StriveEngine —— C/S通訊開源demo(附原始碼)C#元件原始碼