程式簡介
本聊天程式支援區域網路內部用戶端與服務端之間的互相通訊.
原理
啟動服務端後,服務端通過持續監聽用戶端發來的請求,一旦監聽到用戶端傳來的資訊後,兩端便可以互發資訊了.服務端需要綁定一個IP,用於用戶端在網路中尋找並建立串連.資訊發送原理:將手動輸入字串資訊轉換成機器可以識別的位元組數組,然後調用通訊端的Send()方法將位元組數組發送出去.資訊接收原理:調用通訊端的Receive()方法,擷取對端傳來的位元組數組,然後將其轉換成人可以讀懂的字串資訊.
介面設計 - 服務端
IP文字框 name: txtIP port(連接埠號碼)文字框 name: txtPORT 聊天內容文字框 name: txtMsg 發送資訊文字框 name:txtSendMsg
啟動服務按鈕 name: btnServerConn 發送資訊按鈕name: btnSendMsg
服務端代碼:
public partial class FServer : Form { public FServer() { InitializeComponent(); //關閉對文字框的非法線程操作檢查 TextBox.CheckForIllegalCrossThreadCalls = false; } Thread threadWatch = null; //負責監聽用戶端的線程 Socket socketWatch = null; //負責監聽用戶端的通訊端 private void btnServerConn_Click(object sender, EventArgs e) { //定義一個通訊端用於監聽用戶端發來的資訊 包含3個參數(IP4定址協議,流式串連,TCP協議) socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //服務端發送資訊 需要1個IP地址和連接埠號碼 IPAddress ipaddress = IPAddress.Parse(txtIP.Text.Trim()); //擷取文字框輸入的IP地址 //將IP地址和連接埠號碼綁定到網路節點endpoint上 IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(txtPORT.Text.Trim())); //擷取文字框上輸入的連接埠號碼 //監聽綁定的網路節點 socketWatch.Bind(endpoint); //將通訊端的監聽隊列長度限制為20 socketWatch.Listen(20); //建立一個監聽線程 threadWatch = new Thread(WatchConnecting); //將表單線程設定為與背景同步處理 threadWatch.IsBackground = true; //啟動線程 threadWatch.Start(); //啟動線程後 txtMsg文字框顯示相應提示 txtMsg.AppendText("開始監聽用戶端傳來的資訊!" + "\r\n"); } //建立一個負責和用戶端通訊的通訊端 Socket socConnection = null; /// <summary> /// 監聽用戶端發來的請求 /// </summary> private void WatchConnecting() { while (true) //持續不斷監聽用戶端發來的請求 { socConnection = socketWatch.Accept(); txtMsg.AppendText("用戶端串連成功" + "\r\n"); //建立一個通訊線程 ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg); Thread thr = new Thread(pts); thr.IsBackground = true; //啟動線程 thr.Start(socConnection); } } /// <summary> /// 發送資訊到用戶端的方法 /// </summary> /// <param name="sendMsg">發送的字串資訊</param> private void ServerSendMsg(string sendMsg) { //將輸入的字串轉換成 機器可以識別的位元組數組 byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg); //向用戶端發送位元組數組資訊 socConnection.Send(arrSendMsg); //將發送的字串資訊附加到文字框txtMsg上 txtMsg.AppendText("So-flash:" + GetCurrentTime() + "\r\n" + sendMsg + "\r\n"); } /// <summary> /// 接收用戶端發來的資訊 /// </summary> /// <param name="socketClientPara">用戶端通訊端對象</param> private void ServerRecMsg(object socketClientPara) { Socket socketServer = socketClientPara as Socket; while (true) { //建立一個記憶體緩衝區 其大小為1024*1024位元組 即1M byte[] arrServerRecMsg = new byte[1024 * 1024]; //將接收到的資訊存入到記憶體緩衝區,並返回其位元組數組的長度 int length = socketServer.Receive(arrServerRecMsg); //將機器接受到的位元組數群組轉換為人可以讀懂的字串 string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length); //將發送的字串資訊附加到文字框txtMsg上 txtMsg.AppendText("天之涯:" + GetCurrentTime() + "\r\n" + strSRecMsg + "\r\n"); } } //發送資訊到用戶端 private void btnSendMsg_Click(object sender, EventArgs e) { //調用 ServerSendMsg方法 發送資訊到用戶端 ServerSendMsg(txtSendMsg.Text.Trim()); } //快速鍵 Enter 發送資訊 private void txtSendMsg_KeyDown(object sender, KeyEventArgs e) { //如果使用者按下了Enter鍵 if (e.KeyCode == Keys.Enter) { //則調用 伺服器向用戶端發送資訊的方法 ServerSendMsg(txtSendMsg.Text.Trim()); } } /// <summary> /// 擷取當前系統時間的方法 /// </summary> /// <returns>目前時間</returns> private DateTime GetCurrentTime() { DateTime currentTime = new DateTime(); currentTime = DateTime.Now; return currentTime; }
介面設計 - 用戶端
IP文字框 name: txtIP Port文字框 name: txtPort 聊天內容文字框 name:txtMsg 發送資訊文字框 name: txtCMsg
串連到服務端按鈕 name: btnBeginListen 發送訊息按鈕 name: btnSend
用戶端代碼:
public partial class FClient : Form { public FClient() { InitializeComponent(); //關閉對文字框的非法線程操作檢查 TextBox.CheckForIllegalCrossThreadCalls = false; } //建立 1個用戶端通訊端 和1個負責監聽服務端請求的線程 Socket socketClient = null; Thread threadClient = null; private void btnBeginListen_Click(object sender, EventArgs e) { //定義一個套位元組監聽 包含3個參數(IP4定址協議,流式串連,TCP協議) socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //需要擷取文字框中的IP地址 IPAddress ipaddress = IPAddress.Parse(txtIP.Text.Trim()); //將擷取的ip地址和連接埠號碼綁定到網路節點endpoint上 IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(txtPort.Text.Trim())); //這裡用戶端通訊端串連到網路節點(服務端)用的方法是Connect 而不是Bind socketClient.Connect(endpoint); //建立一個線程 用於監聽服務端發來的訊息 threadClient = new Thread(RecMsg); //將表單線程設定為與背景同步處理 threadClient.IsBackground = true; //啟動線程 threadClient.Start(); } /// <summary> /// 接收服務端發來資訊的方法 /// </summary> private void RecMsg() { while (true) //持續監聽服務端發來的訊息 { //定義一個1M的記憶體緩衝區 用於臨時性儲存接收到的資訊 byte[] arrRecMsg = new byte[1024 * 1024]; //將用戶端通訊端接收到的資料存入記憶體緩衝區, 並擷取其長度 int length = socketClient.Receive(arrRecMsg); //將通訊端擷取到的位元組數群組轉換為人可以看懂的字串 string strRecMsg = Encoding.UTF8.GetString(arrRecMsg, 0, length); //將發送的資訊追加到聊天內容文字框中 txtMsg.AppendText("So-flash:" + GetCurrentTime() + "\r\n" + strRecMsg + "\r\n"); } } /// <summary> /// 發送字串資訊到服務端的方法 /// </summary> /// <param name="sendMsg">發送的字串資訊</param> private void ClientSendMsg(string sendMsg) { //將輸入的內容字串轉換為機器可以識別的位元組數組 byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg); //調用用戶端通訊端發送位元組數組 socketClient.Send(arrClientSendMsg); //將發送的資訊追加到聊天內容文字框中 txtMsg.AppendText("天之涯:" + GetCurrentTime() + "\r\n" + sendMsg + "\r\n"); } //點擊按鈕btnSend 向服務端發送資訊 private void btnSend_Click(object sender, EventArgs e) { //調用ClientSendMsg方法 將文字框中輸入的資訊發送給服務端 ClientSendMsg(txtCMsg.Text.Trim()); } //快速鍵 Enter發送資訊 private void txtCMsg_KeyDown(object sender, KeyEventArgs e) { //當游標位於文字框時 如果使用者按下了鍵盤上的Enter鍵 if (e.KeyCode == Keys.Enter) { //則調用用戶端向服務端發送資訊的方法 ClientSendMsg(txtCMsg.Text.Trim()); } } /// <summary> /// 擷取當前系統時間的方法 /// </summary> /// <returns>目前時間</returns> private DateTime GetCurrentTime() { DateTime currentTime = new DateTime(); currentTime = DateTime.Now; return currentTime; }
運行方法
擷取電腦本機IP的方法: 例如:本機IP:192.168.0.3(可能變動) 連接埠號碼port可以隨便寫:1-65535之間的任意整數都行
1.開啟程式 點擊運行
2.在運行欄裡輸入cmd指令
3.輸入查看IP指令: ipconfig
4.擷取當前IP: 192.168.0.3. 當然不同的地方 本機IP有可能不一樣
程式運行展示:
首先 點擊服務端的 啟動服務按鈕 聊天內容出現"開始監聽用戶端傳來的資訊!"
然後 點擊用戶端上的"串連到服務端"按鈕 可以看見服務端上又出現了一行字 "用戶端串連成功"
之後 便可以 兩端進行通訊了
這樣一個簡單的聊天程式就完成了~~~~:)
原始碼下載
用戶端下載 ChatClient.zip 服務端下載 ChatServer.zip
相關推薦
- 基於C# Winform的簡易聊天程式[第二篇-檔案發送]
- 基於C# Winform的簡易聊天程式[第三篇-資訊群發]