Socket實現簡單的指定客戶端傳送資訊(C#)
阿新 • • 發佈:2018-12-22
Socket實現簡單的指定客戶端傳送資訊(效果如下圖)
不多說了,直接上程式碼:
server端:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Net.Sockets; using System.Net; class server { //建立一個和客戶端通訊的套接字 static Socket SocketWatch = null; //定義一個集合,儲存客戶端資訊 static Dictionary<string, Socket> ClientConnectionItems = new Dictionary<string, Socket> { }; public static string cID; static void Main(string[] args) { //埠號(用來監聽的) int port = 6000; IPAddress ip = IPAddress.Any; //將IP地址和埠號繫結到網路節點point上 IPEndPoint ipe = new IPEndPoint(ip, port); //定義一個套接字用於監聽客戶端發來的訊息,包含三個引數(IP4定址協議,流式連線,Tcp協議) SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //監聽繫結的網路節點 SocketWatch.Bind(ipe); //將套接字的監聽佇列長度限制為20 SocketWatch.Listen(20); //負責監聽客戶端的執行緒:建立一個監聽執行緒 Thread threadwatch = new Thread(WatchConnecting); //將窗體執行緒設定為與後臺同步,隨著主執行緒結束而結束 threadwatch.IsBackground = true; //啟動執行緒 threadwatch.Start(); Console.WriteLine("開啟監聽......"); Console.WriteLine("點選輸入任意資料回車退出程式......"); Console.ReadKey(); SocketWatch.Close(); } //監聽客戶端發來的請求 static void WatchConnecting() { Socket connection = null; //持續不斷監聽客戶端發來的請求 while (true) { // string cID; try { connection = SocketWatch.Accept(); } catch (Exception ex) { //提示套接字監聽異常 Console.WriteLine(ex.Message); break; } byte[] idrec = new byte[1024 * 1024]; int length = connection.Receive(idrec); cID = Encoding.UTF8.GetString(idrec, 0, length); ClientConnectionItems.Add(cID, connection); //顯示與客戶端連線情況 Console.WriteLine("\r\n[客戶端\"" + cID + "\"建立連線成功! 客戶端數量:" + ClientConnectionItems.Count + "]"); //獲取客戶端的IP和埠號 IPAddress clientIP = (connection.RemoteEndPoint as IPEndPoint).Address; int clientPort = (connection.RemoteEndPoint as IPEndPoint).Port; string sendmsg = "[" + "本端:" + cID + " 連線服務端成功!]"; byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendmsg); connection.Send(arrSendMsg); //建立一個通訊執行緒 Thread thread = new Thread(recv); //設定為後臺執行緒,隨著主執行緒退出而退出 thread.IsBackground = true; //啟動執行緒 thread.Start(connection); } } static void recv(object socketclientpara) { Socket socketServer = socketclientpara as Socket; while (true) { try { byte[] arrServerRecMsg = new byte[1024 * 1024]; int length = socketServer.Receive(arrServerRecMsg); //將機器接受到的位元組陣列轉換為人可以讀懂的字串 string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length); string ccID = strSRecMsg.Substring(0, 4); int len = strSRecMsg.Length; string hc=cID+":"+strSRecMsg.Substring(4,len-4); Console.WriteLine( DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "]\r\n" + strSRecMsg); //判斷是否包含這個客戶端 bool contains = ClientConnectionItems.ContainsKey(ccID); if (contains) { ClientConnectionItems[ccID].Send(Encoding.UTF8.GetBytes( hc)); } else { Console.WriteLine("輸入有誤,不予轉發\r\n"); } arrServerRecMsg.DefaultIfEmpty(); } catch (Exception) { string temp = ClientConnectionItems.First().Key; //提示套接字監聽異常 Console.WriteLine("\r\n[客戶端\"" + socketServer.RemoteEndPoint + "\"已經中斷連線! 客戶端數量:" + ClientConnectionItems.Count + "]"); ClientConnectionItems.Remove(ClientConnectionItems.First().Key); Console.WriteLine("\r\n[客戶端\"" + temp + "\"已經中斷連線! 客戶端數量:" + ClientConnectionItems.Count + "]"); break; } } } }
client端(這裡只上傳了num3端,想建立更多客戶端改改名稱就行):
using System; using System.Text; using System.Threading; using System.Net.Sockets; using System.Net; class client1 { //建立1個客戶端套接字和1個負責監聽服務端請求的執行緒 static Thread ThreadClient = null; static Socket SocketClient = null; static void Main(string[] args) { try { int port = 6000; string host = "127.0.0.1";//伺服器端ip地址 IPAddress ip = IPAddress.Parse(host); IPEndPoint ipe = new IPEndPoint(ip, port); //定義一個套接字監聽 SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { //客戶端套接字連線到網路節點上,用的是Connect SocketClient.Connect(ipe); //本客戶端的ID string sendsStr = "num3"; ClientSendMsg(sendsStr); } catch (Exception) { Console.WriteLine("連線失敗!\r\n"); Console.ReadLine(); return; } ThreadClient = new Thread(Recv); ThreadClient.IsBackground = true; ThreadClient.Start(); Thread.Sleep(1000); Console.WriteLine("請輸入內容<按Enter鍵傳送>:\r\n"); while(true) { string sendStr = Console.ReadLine(); if (sendStr.Length <= 4) { Console.WriteLine("輸入資訊長度小於5個字元,請重新輸入"); } else if (sendStr.Substring(0,4)=="num3") { Console.WriteLine("請不要給自己傳送資訊"); } else { ClientSendMsg(sendStr); } } } catch (Exception ex) { Console.WriteLine(ex.Message); Console.ReadLine(); } } //接收服務端發來資訊的方法 public static void Recv() { //持續監聽服務端發來的訊息 while (true) { try { //定義一個1M的記憶體緩衝區,用於臨時性儲存接收到的訊息 byte[] arrRecvmsg = new byte[1024 * 1024]; //將客戶端套接字接收到的資料存入記憶體緩衝區,並獲取長度 int length = SocketClient.Receive(arrRecvmsg); //將套接字獲取到的字元陣列轉換為人可以看懂的字串 string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, 0, length); Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "\r\n" + strRevMsg + "\r\n"); } catch (Exception ex) { Console.WriteLine("遠端伺服器已經中斷連線!" + ex.Message + "\r\n"); break; } } } //傳送字元資訊到服務端的方法 public static void ClientSendMsg(string sendMsg) { //將輸入的內容字串轉換為機器可以識別的位元組陣列 byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg); //呼叫客戶端套接字傳送位元組陣列 SocketClient.Send(arrClientSendMsg); } }
注:部分程式碼借鑑於https://blog.csdn.net/luming666/article/details/79125453,我只是做了一些改動,感謝這位博主。