基於c#用Socket做一個局域網聊天對象。本站提示廣大學習愛好者:(基於c#用Socket做一個局域網聊天對象)文章只能為提供參考,不一定能成為您想要的結果。以下是基於c#用Socket做一個局域網聊天對象正文
法式設計成為簡略的辦事端和客戶端之間的通訊, 但經由過程一些辦法可以將這二者停止同一起來, 讓辦事端同樣成為客戶端, 讓客戶端同樣成為辦事端, 使它們之間可以相互隨時不連續的通訊. 斟酌到完成最原始的辦事端和客戶端之間的通訊所須要的步調關於寫如許的法式是很有贊助的.
作為辦事端, 要聲明一個Socket A並綁定(Bind)某一個IP+這個IP指定的通訊端口, 好比這個是127.0.0.1:9050, 然後開端監聽(Listen), Listen可以監聽來自多個IP傳過去的銜接要求, 詳細可以同時銜接幾個客戶端, Listen辦法中可以設定一個參數. 假如Listen到某一個客戶端發來銜接要求了, 這時候界說一個新的Socket B專門擔任與這個客戶真個通訊, Socket B = A.Accept(). 這時候可以獲得這個客戶真個IP和端口, IPEndPoint C = (IPEndPoint)B.RemoteEndPoint, C.Address和C.Port分離表現客戶端C的IP地址和端口. 這時候經由過程B.Send()辦法便可以給C發送新聞了, B.Receive()可以吸收客戶端C發來的信息.
作為客戶端, 也須要聲明一個Socket D並綁定某一個IP+本機一個未被占用的端口, 界說IPEndPoint E表現要停止銜接的辦事端Socket, 要指明E的IP和端口, 如許才可以停止端口對端口之間的通訊, 接上去便可以測驗考試D.Connect(E), 銜接勝利以後便可以發送和吸收數據了, D.Send(), D.Receive.
發送新聞時, 數據都是以字節或字節數組為單元停止傳輸的, 好比我客戶端D要發送"Hello World"則要如許寫: D.Send(Encoding.ASCII.GetBytes("Hello World")). 接收新聞時, 也是以字節或字節數組, 好比辦事端要接收D適才發送的Hello World, 可以如許寫: Byte[] data = new Byte[1024]; int receivedDataLength = B.Receive(data); string stringdata = Encoding.ASCII.GetString(data, 0, receivedDataLength); stringdata這時候就是Hello World.
下面只是年夜概的論述了辦事端與客戶端之間的通訊進程, 在網上找到了詳細的代碼例子, 也貼過去參考參考. 這個例子未將辦事端與客戶端同一起來, 他是分離寫辦事端和客戶真個.
辦事端代碼
using System; using System; using System.Net; using System.Net.Sockets; using System.Text; namespace tcpserver { /// <summary> /// Class1 的摘要解釋。 /// </summary> class server { /// <summary> /// 運用法式的主進口點。 /// </summary> [STAThread] static void Main( string [] args) { // // TODO: 在此處添加代碼以啟動運用法式 // int recv; // 用於表現客戶端發送的信息長度 byte [] data;// = new byte [ 1024 ]; // 用於緩存客戶端所發送的信息,經由過程socket傳遞的信息必需為字節數組 IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050 ); // 本機預應用的IP和端口 Socket newsock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); newsock.Bind(ipep); // 綁定 newsock.Listen( 10 ); // 監聽 Console.WriteLine( " waiting for a client " ); Socket client = newsock.Accept(); //當有可用的客戶端銜接測驗考試時履行,並前往一個新的socket,用於與客戶端之間的通訊 IPEndPoint clientip = (IPEndPoint)client.RemoteEndPoint; Console.WriteLine( " connect with client: " + clientip.Address + " at port: " + clientip.Port); string welcome = " welcome here! " ; data = Encoding.ASCII.GetBytes(welcome); client.Send(data,data.Length,SocketFlags.None); // 發送信息 while ( true ) { // 用逝世輪回來赓續的從客戶端獲得信息 data = new byte [ 1024 ]; recv = client.Receive(data); Console.WriteLine( " recv= " + recv); if (recv == 0 ) // 當信息長度為0,解釋客戶端銜接斷開 break ; Console.WriteLine(Encoding.ASCII.GetString(data, 0 ,recv)); client.Send(data,recv,SocketFlags.None); } Console.WriteLine( " Disconnected from " + clientip.Address); client.Close(); newsock.Close(); } } }
客戶端代碼
using System; using System.Net; using System.Net.Sockets; using System.Text; namespace tcpclient { /// <summary> /// Class1 的摘要解釋。 /// </summary> class client { /// <summary> /// 運用法式的主進口點。 /// </summary> [STAThread] static void Main(string[] args) { // // TODO: 在此處添加代碼以啟動運用法式 // byte[] data = new byte[1024]; Socket newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); newclient.Bind(new IPEndPoint(IPAddress.Any, 905)); Console.Write(" please input the server ip: "); string ipadd = Console.ReadLine(); Console.WriteLine(); Console.Write(" please input the server port: "); int port = Convert.ToInt32(Console.ReadLine()); IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ipadd), port); // 辦事器的IP和端口 try { // 由於客戶端只是用來向特定的辦事器發送信息,所以不須要綁定本機的IP和端口。不須要監聽。 newclient.Connect(ie); } catch (SocketException e) { Console.WriteLine(" unable to connect to server "); Console.WriteLine(e.ToString()); return; } int receivedDataLength = newclient.Receive(data); string stringdata = Encoding.ASCII.GetString(data, 0, receivedDataLength); Console.WriteLine(stringdata); while (true) { string input = Console.ReadLine(); if (input == " exit ") break; newclient.Send(Encoding.ASCII.GetBytes(input)); data = new byte[1024]; receivedDataLength = newclient.Receive(data); stringdata = Encoding.ASCII.GetString(data, 0, receivedDataLength); Console.WriteLine(stringdata); } Console.WriteLine(" disconnect from sercer "); newclient.Shutdown(SocketShutdown.Both); newclient.Close(); } } }
下面的辦事端和客戶端都是掌握台運用法式, 想方法做一個窗體類型的, 思緒就是另起一個線程, 這個線程專門擔任兩頭樹立銜接. 假如不采取另起線程的辦法, 當期待銜接而沒有銜接上, 或許自動銜接, 辦事端還沒有響應時, 法式就會湧現沒有呼應的假逝世狀況.
當這個線程將兩個端口銜接勝利後, 就讓法式進入一個逝世輪回, 這個逝世輪回擔任赓續的吸收能否有新聞傳來, 傳來的話就在txtGetMsg中顯示出來:
while (true) // 用逝世輪回來赓續的獲得信息 { data = new byte[1024]; recv = newclient.Receive(data); uiContext.Send(new SendOrPostCallback( state => { int txtGetMsgLength = txtGetMsg.Text.Length; string recMsg = "Friend: " + System.DateTime.Now.ToString() + "\n " +Encoding.Unicode.GetString(data, 0, recv) + "\n"; txtGetMsg.AppendText(recMsg); txtGetMsg.Select(txtGetMsgLength, recMsg.Length - Encoding.Unicode.GetString(data, 0, recv).Length - 1); txtGetMsg.SelectionColor = Color.Red; }), null); }
假如按下發送新聞的按鈕, 則發送txtSendMsg中的文本, 我寫的是用Unicode編碼, 所以可以發送中文字符.
private void btnSendMsg_Click(object sender, EventArgs e) { string input = txtSendMsg.Text; if (input == "") { MessageBox.Show("新聞不克不及為空!", "發送新聞失足"); txtSendMsg.Focus(); } else { if (meIsClient) { newclient.Send(Encoding.Unicode.GetBytes(input)); string showText = "Me: " + System.DateTime.Now.ToString() + "\n " + input + "\n"; int txtGetMsgLength = txtGetMsg.Text.Length; txtGetMsg.AppendText(showText); txtGetMsg.Select(txtGetMsgLength, showText.Length - 1 - input.Length); txtGetMsg.SelectionColor = Color.Blue; txtSendMsg.Text = ""; } else { client.Send(Encoding.Unicode.GetBytes(input)); string showText = "Me " + System.DateTime.Now.ToString() + "\n " + input + "\n"; int txtGetMsgLength = txtGetMsg.Text.Length; txtGetMsg.AppendText(showText); txtGetMsg.Select(txtGetMsgLength, showText.Length - 1 - input.Length); txtGetMsg.SelectionColor = Color.Blue; txtSendMsg.Text = ""; } } }
法式的運轉後果:
以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。