C#Winform窗体实现服务端和客户端通信例子(TCP/IP)
Winform窗體實現服務端和客戶端通信的例子,是參考這個地址
http://www.cnblogs.com/longwu/archive/2011/08/25/2153636.html
進行了一些異常處理,提示信息的補充,還有新增獲取本地IP的方法
1、通信原理
1)服務端與客戶端
?啟動服務端后,服務端通過持續監聽客戶端發來的請求,一旦監聽到客戶端傳來的信息(請求),兩端便可以互發信息了.
服務端需要綁定一個IP,用于客戶端在網絡中尋找并建立連接(支持局域網內部客戶端與服務端之間的互相通信)
2)信息發送原理
將手動輸入字符串信息轉換成機器可以識別的字節數組,然后調用套接字的Send()方法將字節數組發送出去
3)信息接收原理
調用套接字的Receive()方法,獲取對端傳來的字節數組,然后將其轉換成人可以讀懂的字符串信息
2、界面設計
1)服務端
文本框類
IP地址, name:txtIP ; 本地端口,name:txtPort;
聊天信息,name:txtMsg;發送消息:txtSendMsg
按鈕類
獲取IP, name :btnGetLocalIP, 獲取本地的IP的方法
啟動服務,name:btnServerConn, 支持服務端與客戶端通信的前提
發送消息,name:btnSendMsg ,發送消息到客戶端的方法
2)客戶端
文本框類
IP地址, name:txtIP ; 本地端口,name:txtPort;
聊天信息,name:txtMsg;發送消息:txtClientSendMsg
按鈕類
連接服務端,name:btnListenServer, 客戶端連接服務端的方法
發送消息,name:btnSendMsg ,發送消息到服務端的方法
3、源碼例子
1)服務端代碼
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms;namespace TcpMsgServer {public partial class FrmServer : Form{public FrmServer(){InitializeComponent();//關閉對文本框的非法線程操作檢查TextBox.CheckForIllegalCrossThreadCalls = false;}Thread threadWatch = null; //負責監聽客戶端的線程Socket socketWatch = null; //負責監聽客戶端的套接字 /// <summary>/// 啟動服務/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnServerConn_Click(object sender, EventArgs e){try{//定義一個套接字用于監聽客戶端發來的信息 包含3個參數(IP4尋址協議,流式連接,TCP協議)socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//服務端發送信息 需要1個IP地址和端口號IPAddress ipaddress = IPAddress.Parse(this.txtIP.Text.Trim()); //獲取文本框輸入的IP地址//將IP地址和端口號綁定到網絡節點endpoint上 IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(this.txtPort.Text.Trim())); //獲取文本框上輸入的端口號//監聽綁定的網絡節點 socketWatch.Bind(endpoint);//將套接字的監聽隊列長度限制為20socketWatch.Listen(20);//創建一個監聽線程 threadWatch = new Thread(WatchConnecting);//將窗體線程設置為與后臺同步threadWatch.IsBackground = true;//啟動線程 threadWatch.Start();//啟動線程后 txtMsg文本框顯示相應提示txtMsg.AppendText("開始監聽客戶端傳來的信息!" + "\r\n");this.btnServerConn.Enabled = false;}catch (Exception ex) {txtMsg.AppendText("服務端啟動服務失敗!" + "\r\n");this.btnServerConn.Enabled = true;}}//創建一個負責和客戶端通信的套接字 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){try{//將輸入的字符串轉換成 機器可以識別的字節數組byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg);//向客戶端發送字節數組信息 socConnection.Send(arrSendMsg);//將發送的字符串信息附加到文本框txtMsg上txtMsg.AppendText("服務器 " + GetCurrentTime() + "\r\n" + sendMsg + "\r\n");}catch (Exception ex) {txtMsg.AppendText("客戶端已斷開連接,無法發送信息!" + "\r\n");}}/// <summary>/// 接收客戶端發來的信息 /// </summary>/// <param name="socketClientPara">客戶端套接字對象</param>private void ServerRecMsg(object socketClientPara){Socket socketServer = socketClientPara as Socket;while (true){//創建一個內存緩沖區 其大小為1024*1024字節 即1Mbyte[] arrServerRecMsg = new byte[1024 * 1024];try{//將接收到的信息存入到內存緩沖區,并返回其字節數組的長度int length = socketServer.Receive(arrServerRecMsg);//將機器接受到的字節數組轉換為人可以讀懂的字符串string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);//將發送的字符串信息附加到文本框txtMsg上 txtMsg.AppendText("天涯 " + GetCurrentTime() + "\r\n" + strSRecMsg + "\r\n");}catch (Exception ex) {txtMsg.AppendText("客戶端已斷開連接!" + "\r\n");break;}}}/// <summary>/// 發送消息到客戶端/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSendMsg_Click(object sender, EventArgs e){//調用 ServerSendMsg方法 發送信息到客戶端ServerSendMsg(this.txtSendMsg.Text.Trim());this.txtSendMsg.Clear();}/// <summary>/// 快捷鍵 Enter 發送信息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void txtSendMsg_KeyDown(object sender, KeyEventArgs e){//如果用戶按下了Enter鍵if (e.KeyCode == Keys.Enter){//則調用 服務器向客戶端發送信息的方法 ServerSendMsg(txtSendMsg.Text.Trim());this.txtSendMsg.Clear();}}/// <summary>/// 獲取當前系統時間的方法/// </summary>/// <returns>當前時間</returns>private DateTime GetCurrentTime(){DateTime currentTime = new DateTime();currentTime = DateTime.Now;return currentTime;}/// <summary>/// 獲取本地IPv4地址/// </summary>/// <returns></returns>public IPAddress GetLocalIPv4Address() {IPAddress localIpv4 = null;//獲取本機所有的IP地址列表IPAddress[] IpList = Dns.GetHostAddresses(Dns.GetHostName());//循環遍歷所有IP地址foreach (IPAddress IP in IpList) {//判斷是否是IPv4地址if (IP.AddressFamily == AddressFamily.InterNetwork){localIpv4 = IP;}else {continue;}}return localIpv4;}/// <summary>/// 獲取本地IP事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnGetLocalIP_Click(object sender, EventArgs e){//接收IPv4的地址IPAddress localIP = GetLocalIPv4Address();//賦值給文本框this.txtIP.Text = localIP.ToString();}} }2)客戶端代碼
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms;namespace TcpMsgClient {public partial class FrmClient : Form{public FrmClient(){InitializeComponent();//關閉對文本框的非法線程操作檢查TextBox.CheckForIllegalCrossThreadCalls = false;}//創建 1個客戶端套接字 和1個負責監聽服務端請求的線程 Socket socketClient = null;Thread threadClient = null;/// <summary>/// 連接服務端事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnListenServer_Click(object sender, EventArgs e){//定義一個套字節監聽 包含3個參數(IP4尋址協議,流式連接,TCP協議)socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//需要獲取文本框中的IP地址IPAddress ipaddress = IPAddress.Parse(this.txtIP.Text.Trim());//將獲取的ip地址和端口號綁定到網絡節點endpoint上IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(this.txtPort.Text.Trim()));//這里客戶端套接字連接到網絡節點(服務端)用的方法是Connect 而不是Bindtry{socketClient.Connect(endpoint);this.txtMsg.AppendText("客戶端連接服務端成功!" + "\r\n");this.btnListenServer.Enabled = false;//創建一個線程 用于監聽服務端發來的消息threadClient = new Thread(RecMsg);//將窗體線程設置為與后臺同步threadClient.IsBackground = true;//啟動線程 threadClient.Start();}catch (Exception ex) {this.txtMsg.AppendText("遠程服務端斷開,連接失敗!" + "\r\n");} }/// <summary>/// 接收服務端發來信息的方法/// </summary>private void RecMsg(){while (true) //持續監聽服務端發來的消息 {try{//定義一個1M的內存緩沖區 用于臨時性存儲接收到的信息byte[] arrRecMsg = new byte[1024 * 1024];//將客戶端套接字接收到的數據存入內存緩沖區, 并獲取其長度int length = socketClient.Receive(arrRecMsg);//將套接字獲取到的字節數組轉換為人可以看懂的字符串string strRecMsg = Encoding.UTF8.GetString(arrRecMsg, 0, length);//將發送的信息追加到聊天內容文本框中txtMsg.AppendText("服務端 " + GetCurrentTime() + "\r\n" + strRecMsg + "\r\n");}catch (Exception ex) {this.txtMsg.AppendText("遠程服務器已中斷連接!"+"\r\n");this.btnListenServer.Enabled = true;break;}}}/// <summary>/// 發送字符串信息到服務端的方法/// </summary>/// <param name="sendMsg">發送的字符串信息</param>private void ClientSendMsg(string sendMsg){try { //將輸入的內容字符串轉換為機器可以識別的字節數組byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);//調用客戶端套接字發送字節數組 socketClient.Send(arrClientSendMsg);//將發送的信息追加到聊天內容文本框中txtMsg.AppendText("天涯 " + GetCurrentTime() + "\r\n" + sendMsg + "\r\n");}catch(Exception ex){this.txtMsg.AppendText("遠程服務器已中斷連接,無法發送消息!" + "\r\n");}}private void btnSendMsg_Click(object sender, EventArgs e){//調用ClientSendMsg方法 將文本框中輸入的信息發送給服務端ClientSendMsg(this.txtClientSendMsg.Text.Trim());this.txtClientSendMsg.Clear();}private void txtClientSendMsg_KeyDown(object sender, KeyEventArgs e){//當光標位于文本框時 如果用戶按下了鍵盤上的Enter鍵 if (e.KeyCode == Keys.Enter){//則調用客戶端向服務端發送信息的方法ClientSendMsg(this.txtClientSendMsg.Text.Trim());this.txtClientSendMsg.Clear();}}/// <summary>/// 獲取當前系統時間的方法/// </summary>/// <returns>當前時間</returns>private DateTime GetCurrentTime(){DateTime currentTime = new DateTime();currentTime = DateTime.Now;return currentTime;}} }4、程序演示
1)正常情況
運行服務端程序,輸入本地的IP地址,不知道可以點擊獲取本地IP按鈕,輸入本地端口,點擊啟動服務按鈕,
消息框會出現開始監聽客戶端信息,表示服務端啟動服務成功
運行客戶端程序,輸入服務端的IP和端口,點擊連接服務端按鈕,當服務端的消息框出現客戶端連接成功,
表示連接服務端成功
服務端啟動服務成功,客戶端連接服務端成功,可以兩端進行通信發消息
2)異常處理
原先參考的源碼未做異常處理,導致退出程序報錯,提示未友好等
當客戶端異常處理
服務端中斷開連接,自動提示
服務端中斷連接,無法發送消息
服務端異常處理
客戶端斷開連接,自動提示
客戶端斷開連接,無法發送消息
Ps: 這個例子經過本人測試,下面是源碼下載路徑:
http://pan.baidu.com/s/1nvRrCV3
總結
以上是生活随笔為你收集整理的C#Winform窗体实现服务端和客户端通信例子(TCP/IP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: webstorm中配置svn
- 下一篇: 魔兽世界怀旧服圣骑士天赋怎么加点 圣骑士