主要分為兩部分來寫,分別是Receive and Send Socket
如果懶得寫class,可以直接下載這三個檔案來用
RecieveDataEventArgs.cs
UdpSocketHoster.cs
UdpSocketSender.cs
新增一個WPF的專案,專案名稱命名為AppicationName。
Receive Socket
加入ReceiveDataEventArgs,準備給UdpSocketHoster使用。ReceiveDataEventArgs.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApplicationName { public class ReceiveDataEventArgs : EventArgs { #region Fields (1) private object mData; #endregion Fields #region Constructors (1) public ReceiveDataEventArgs(object data) { this.mData = data; } #endregion Constructors #region Properties (1) public object Data { get { return mData; } } #endregion Properties } }
UdpSocketHoster.cs
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; namespace ApplicationName { public class UdpSocketHoster { #region Fields (3) private Thread mListenThread; private int mReceiverBuffer = 65536; private Socket mSocket; #endregion Fields #region Properties (3) public string Ip { get; set; } public int Port { get; set; } public int ReceiverBuffer { get { return mReceiverBuffer; } set { mReceiverBuffer = value; } } #endregion Properties #region Delegates and Events (3) // Events (3) public event EventHandlerReceivedData; public event EventHandler StartListening; public event EventHandler StopListening; #endregion Delegates and Events #region Methods (4) // Public Methods (3) public void Start() { if (StartListening != null) { StartListening(this, new EventArgs()); } mListenThread = new Thread(new ParameterizedThreadStart(startListen)); mListenThread.Start(); } public void Start(string ip, int port) { this.Ip = ip; this.Port = port; Start(); } public void Stop() { if (StopListening != null) { StopListening(this, new EventArgs()); } mSocket.Close(); mListenThread.Abort(); } // Private Methods (1) private void startListen(object sender) { //Setting Endpoint IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, Port); mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //Binding Endpoint mSocket.Bind(endpoint); //Getting Client Ip IPEndPoint clientEndpoint = new IPEndPoint(IPAddress.Any, 0); EndPoint Remote = (EndPoint)(clientEndpoint); //Start loop for receiving data while (true) { try { int recv; byte[] receivePackage = new byte[mReceiverBuffer]; //Receive data from client recv = mSocket.ReceiveFrom(receivePackage, ref Remote); //remove empty byte byte[] cropped = new byte[recv]; Array.Copy(receivePackage, 0, cropped, 0, recv); String str = System.Text.Encoding.UTF8.GetString(cropped, 0, cropped.Length); ////Deserialize data //BinaryFormatter bf = new BinaryFormatter(); //MemoryStream stream = new MemoryStream(receivePackage); //object data = bf.Deserialize(stream); if (ReceivedData != null) { ReceivedData(this, new ReceiveDataEventArgs(str)); } } catch (Exception ex) { throw; } } } #endregion Methods } }
先準備好這兩個class之後就可以開始在MainWindow裡面用了
MainWindow.cs
public partial class MainWindow : Window { UdpSocketHoster myhoster = new UdpSocketHoster(); public MainWindow() { InitializeComponent(); // initial socket hoster initSocket(); } public void initSocket() { myhoster = new UdpSocketHoster(); myhoster.ReceivedData += (o, e) => ReceiveData8000(e.Data.ToString()); myhoster.StartListening += (o, e) => Console.WriteLine("Start Hosting..."); myhoster.StopListening += (o, e) => Console.WriteLine("Stop Hosting..."); myhoster.Start("127.0.0.1", 8000); } // receive _data string public void ReceiveData8000(String _data) { Dispatcher.BeginInvoke(new Action(() => { label_socket.Content = _data; ColorChange(_data); })); } // stop host when exit private void Window_main_Closed(object sender, EventArgs e) { myhoster.Stop(); } }
1. myhoster.Start("127.0.0.1", 8000)就是設定host的IP位置跟port。ps. 本機的IP是127.0.0.1
2. _data則是收到socket的字串資料,收到_data之後可以做後面的處理。
3. 最後記得在關掉程式的時候,也要把host停掉,不然host會在背後一直跑。
Send Socket
在專案中加入UdpSocketSenderUdpSocketSender.cs
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Threading.Tasks; namespace ApplicationName { public class UdpSocketSender { #region Fields (1) private int mPackageBuffer = 1024; #endregion Fields #region Constructors (1) public UdpSocketSender(string ip, int port) { this.Ip = ip; this.Port = port; } #endregion Constructors #region Properties (3) public string Ip { get; set; } public int PackageBuffer { get { return mPackageBuffer; } set { mPackageBuffer = value; } } public int Port { get; set; } #endregion Properties #region Methods (1) // Public Methods (1) public void Send(string data) { //Setting Server Endpoint IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(Ip), Port); Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); server.EnableBroadcast = true; //Serialize Data byte[] package = new byte[mPackageBuffer]; BinaryFormatter bf = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); bf.Serialize(stream, data); package = stream.ToArray(); //Send Data byte[] b = System.Text.Encoding.UTF8.GetBytes(data); server.SendTo(b, b.Length, SocketFlags.None, endPoint); } #endregion Methods } }
接著只要在MainWindow.cs裡面加入宣告
UdpSocketSender mysender = new UdpSocketSender("127.0.0.1", 8000);準備一個mysender負責對IP:127.0.0.1(本機) port:8000傳送資料。
之後就可以直接用mysend來傳送字串"Test"。
mysender.Send("Test");
最後放上完整的MainWindow程式碼(包括receive跟send功能)
public partial class MainWindow : Window { UdpSocketHoster myhoster = new UdpSocketHoster(); UdpSocketSender mysender = new UdpSocketSender("127.0.0.1", 8000); public MainWindow() { InitializeComponent(); // initial socket hoster initSocket(); // send socket mysender.Send("Test"); } public void initSocket() { myhoster = new UdpSocketHoster(); myhoster.ReceivedData += (o, e) => ReceiveData8000(e.Data.ToString()); myhoster.StartListening += (o, e) => Console.WriteLine("Start Hosting..."); myhoster.StopListening += (o, e) => Console.WriteLine("Stop Hosting..."); myhoster.Start("127.0.0.1", 8000); } // receive _data string public void ReceiveData8000(String _data) { Dispatcher.BeginInvoke(new Action(() => { label_socket.Content = _data; ColorChange(_data); })); } // stop host when exit private void Window_main_Closed(object sender, EventArgs e) { myhoster.Stop(); } }
沒有留言:
張貼留言