UDP Server 程式碼(三)
該版本,修改 (Fom)Invok => (Control)Invok
1: ((System.Windows.Forms.Form)mOwner).Invoke( 2: mSetUdpReceivedDlg, 3: mStream, 4: (IPEndPoint)mRemotePoint 5: );改成
1: ((System.Windows.Forms.Control)mOwner).Invoke( 2: mSetUdpReceivedDlg, 3: mStream, 4: (IPEndPoint)mRemotePoint 5: );UDP Server 程式碼
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net;using System.Net.Sockets;using System.IO;namespace jgeClassLib.Net{ /// <summary> /// 事件委派宣告 /// </summary>public delegate void UdpEventHandler(object sender, UdpEventArgs e);
public class jUdpServer
{ /// <summary> /// 非同步接收資料的回呼 /// </summary>private void EndRecvCallBack(IAsyncResult result)
{ try { /*傳回非同步物件*/ Socket mResultSocket = result.AsyncState as Socket; /*呼叫 EndReceiveFrom 非同步接收*/int mRecvBytes = mResultSocket.EndReceiveFrom(result, ref mRemotePoint);
/*將資料置入Stream */Stream mStream = BytesToStream(mRecvBuffer, mRecvBytes);
/* Invoke */((System.Windows.Forms.Control)mOwner).Invoke(
mSetUdpReceivedDlg,
mStream,
(IPEndPoint)mRemotePoint
); //.. List<byte>}
catch (Exception ex) { //((System.Windows.Forms.Control)m_Owner).Invoke(m_SetUdpReceivedDlg, ex.Message); //??????}
finally { /*重新呼叫非同步接收*/mSocketServer.BeginReceiveFrom(
mRecvBuffer,
0,
mRecvBuffer.Length,
SocketFlags.None,
ref mRemotePoint, new AsyncCallback(EndRecvCallBack),mSocketServer
);
}
}
#region 公用程式 Bytes、Stream 轉換 /// <summary> /// 將 Byte陣列 轉為 Stream /// </summary> /// <returns>Stream</returns>public static Stream BytesToStream(byte[] bytes)
{ Stream stream = new MemoryStream(bytes); return stream;}
public static Stream BytesToStream(byte[] bytes, int Length)
{ Stream stream = new MemoryStream(bytes, 0, Length); return stream;}
/// <summary> /// 將 Stream 轉為 Byte陣列 /// </summary>public static byte[] StreamToBytes(Stream stream)
{byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
/*將 stream 指針指向開頭*/stream.Seek(0, SeekOrigin.Begin);
return bytes;}
#endregion /// <summary> /// 委派處理函式 /// </summary> //private void OnUdpReceivedText(Stream msg, string ip, int port)private void OnUdpReceivedText(Stream msg, IPEndPoint ipend)
{ UdpEventArgs e = new UdpEventArgs(msg, ipend);if (UdpReceived != null) //. 當事件變數不為 null 則執行之
{ UdpReceived(this, e);}
}
/// <summary> /// 委派宣告 /// </summary>private delegate void SetUdpReceived(Stream msg, IPEndPoint ipend);
/// <summary> /// 委派欄位 /// </summary> private SetUdpReceived mSetUdpReceivedDlg; /// <summary> /// 本機端 Socket物件 /// </summary>private Socket mSocketServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
/// <summary> /// 接收資料的緩衝區 /// </summary>private byte[] mRecvBuffer = new byte[10240];
/// <summary> /// 初始化遠端IP和 Port端點物件 /// </summary>private EndPoint mRemotePoint = new IPEndPoint(IPAddress.Any, 0);
/// <summary> /// 服務 Port /// </summary>private int mPort = 0;
/// <summary> /// 儲存擁有者 /// </summary>private object mOwner;
/// <summary> /// UDP Received 事件 /// </summary>public event UdpEventHandler UdpReceived;
/// <summary> /// 建構式 /// </summary>private IPEndPoint mIPPoint; ///*指定要以機器上所有的網路介面,開啟的 Port*/
public jUdpServer(object Owner,string IP, int APort)
{mOwner = Owner;
mPort = APort;
mIPPoint = new IPEndPoint(IPAddress.Parse(IP), mPort);InitUDP();
}
public jUdpServer(object Owner, int APort)
{mOwner = Owner;
mPort = APort;
mIPPoint = new IPEndPoint(IPAddress.Any, mPort);InitUDP();
}
private void InitUDP()
{ /*初始化Sockt物件*/ mSocketServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); /*指定要以機器上所有的網路介面,開啟的 Port*/ // IPEndPoint mIPPoint = new IPEndPoint(IPAddress.Any, 0); /*繫結 IP 和 Port 資訊*/mSocketServer.Bind(mIPPoint);
/*設定委派處理函式*/mSetUdpReceivedDlg = OnUdpReceivedText;
//..啟動非同步接受資料mSocketServer.BeginReceiveFrom(
mRecvBuffer,
0,
mRecvBuffer.Length,
SocketFlags.None,
ref mRemotePoint, new AsyncCallback(EndRecvCallBack),mSocketServer
);
}
/*建立以 UDP 為協定的 Socket*/ Socket m_SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPAddress m_RemoteAddress = new IPAddress(0);public int UDP_Send(String RemoteIP, int RemotePort, byte[] TxBuffer, int ByteCount)
{ //("遠端IP位置 : "); // IPAddress m_RemoteAddress = IPAddress.Parse(RemoteIP) ; // if (m_RemoteAddress != null)if (IPAddress.TryParse(RemoteIP, out m_RemoteAddress))
{ /*初始化IPEndPoint物件,表示要連結的遠端IP位置和Port號*/ EndPoint m_IPPoint = new IPEndPoint(m_RemoteAddress, RemotePort); try { /*送出訊息*/m_SocketClient.SendTo(TxBuffer, m_IPPoint);
return (0);}
catch { return (-1);}
}
return (-1);}
}
/// <summary> /// 定義專用事件參數類別 /// </summary>public class UdpEventArgs : EventArgs
{private IPEndPoint mIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
private Stream mMSG = new MemoryStream();
public UdpEventArgs(Stream msg, IPEndPoint ipend) {MSG = msg;
mIpEndPoint.Address = ipend.Address;
mIpEndPoint.Port = ipend.Port;
}
public IPEndPoint EndPoint { get { return mIpEndPoint; }private set { mIpEndPoint = value; }
}
public Stream MSG { get { return mMSG; }private set { mMSG = value; }
}
}
}
使用該 Classint iPort = 5168;UDP_Server udpADAM;啟動UDP封包接收伺服
udpADAM = new UDP_Server(this, iPort); // 建立物件udpADAM.UdpReceived += onUdpReceived; // 串接事件
事件程式可以處裡多個 Port 的服務
private void DoUdpReceived(object sender, UdpEventArgs e)
{Byte[] bytes = jUdpServer.StreamToBytes(e.MSG);
string str = System.Text.Encoding.Default.GetString(bytes); /* Other Code ... */}
沒有留言:
張貼留言