主要分為兩部分來寫,分別是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 EventHandler ReceivedData;
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();
}
}
沒有留言:
張貼留言