異世界


2012年5月22日 星期二

UDP Server(一)

UDP Server 程式碼(一)
   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Net;
   6: using System.Net.Sockets;
   7: using System.IO;
   8:  
   9: namespace jge_UdpServer
  10: {
  11:     /// <summary>
  12:     /// 事件委派宣告
  13:     /// </summary>
  14:     public delegate void UdpEventHandler(object sender, UdpEventArgs e);
  15:  
  16:     public class UDP_Server
  17:     {
  18:         /// <summary>
  19:         /// 非同步接收資料的回呼
  20:         /// </summary>
  21:         private void EndRecvCallBack(IAsyncResult result)
  22:         {
  23:             try
  24:             {
  25:                 /*傳回非同步物件*/
  26:                 Socket mResultSocket = result.AsyncState as Socket;
  27:  
  28:                 /*呼叫 EndReceiveFrom 非同步接收*/
  29:                 int mRecvBytes = mResultSocket.EndReceiveFrom(result, ref mRemotePoint);
  30:  
  31:                 /*將資料置入Stream */
  32:                 Stream mStream = BytesToStream(mRecvBuffer, mRecvBytes);
  33:  
  34:                 /* Invoke */
  35:                 ((System.Windows.Forms.Form)mOwner).Invoke(
  36:                     mSetUdpReceivedDlg, 
  37:                     mStream, 
  38:                     ((IPEndPoint)mRemotePoint).Address.ToString()
  39:                   ); //.. List<byte>
  40:  
  41:             }
  42:             catch (Exception ex)
  43:             {
  44:                 //((System.Windows.Forms.Form)m_Owner).Invoke(m_SetUdpReceivedDlg, ex.Message); //??????
  45:             }
  46:             finally
  47:             {
  48:                 /*重新呼叫非同步接收*/
  49:                 mSocketServer.BeginReceiveFrom(
  50:                     mRecvBuffer, 
  51:                     0, 
  52:                     mRecvBuffer.Length, 
  53:                     SocketFlags.None, 
  54:                     ref mRemotePoint, 
  55:                     new AsyncCallback(EndRecvCallBack), 
  56:                     mSocketServer
  57:                   );
  58:             }
  59:  
  60:         }
  61:  
  62:         /// <summary>
  63:         /// 將 Byte陣列 轉為 Stream
  64:         /// </summary>
  65:         /// <returns>Stream</returns>
  66:         public static Stream BytesToStream(byte[] bytes)
  67:         {
  68:             Stream stream = new MemoryStream(bytes);
  69:             return stream;
  70:         }
  71:  
  72:         public static Stream BytesToStream(byte[] bytes, int Length)
  73:         {
  74:             Stream stream = new MemoryStream(bytes, 0, Length);
  75:             return stream;
  76:         }
  77:         /// <summary>
  78:         /// 將 Stream 轉為 Byte陣列
  79:         /// </summary>
  80:         public static byte[] StreamToBytes(Stream stream)
  81:         {
  82:             byte[] bytes = new byte[stream.Length];
  83:             stream.Read(bytes, 0, bytes.Length);
  84:  
  85:             /*將 stream 指針指向開頭*/
  86:             stream.Seek(0, SeekOrigin.Begin);
  87:             return bytes;
  88:         }
  89:  
  90:         /// <summary>
  91:         /// 委派處理函式
  92:         /// </summary>
  93:         private void OnUdpReceivedText(Stream msg, string ip)
  94:         {
  95:             UdpEventArgs e = new UdpEventArgs(msg, ip);
  96:  
  97:             if (UdpReceived != null) //. 當事件變數不為 null 則執行之
  98:             {
  99:                 UdpReceived(this, e);
 100:             }
 101:         }
 102:  
 103:         /// <summary>
 104:         /// 委派宣告
 105:         /// </summary>
 106:         private delegate void SetUdpReceived(Stream msg, string ip);        
 107:         
 108:         /// <summary>
 109:         /// 委派欄位
 110:         /// </summary>
 111:         private SetUdpReceived mSetUdpReceivedDlg;
 112:         /// <summary>
 113:         /// 本機端 Socket物件
 114:         /// </summary>
 115:         private Socket mSocketServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
 116:         /// <summary>
 117:         /// 接收資料的緩衝區
 118:         /// </summary>
 119:         private byte[] mRecvBuffer=new byte[10240];
 120:         /// <summary>
 121:         /// 初始化遠端IP和 Port端點物件
 122:         /// </summary>
 123:         private EndPoint mRemotePoint = new IPEndPoint(IPAddress.Any, 0);
 124:         /// <summary>
 125:         /// 儲存擁有者
 126:         /// </summary>
 127:         private object mOwner;
 128:         /// <summary>
 129:         /// UDP Received 事件
 130:         /// </summary>
 131:         public event UdpEventHandler UdpReceived; 
 132:  
 133:         /// <summary>
 134:         /// 建構式
 135:         /// </summary>
 136:         public UDP_Server(object Owner, int APort)
 137:         {
 138:             mOwner = Owner;
 139:  
 140:             /*初始化Sockt物件*/
 141:             mSocketServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
 142:  
 143:             /*指定要以機器上所有的網路介面,開啟的 Port*/
 144:             IPEndPoint mIPPoint = new IPEndPoint(IPAddress.Any, APort);
 145:  
 146:             /*繫結 IP 和 Port 資訊*/
 147:             mSocketServer.Bind(mIPPoint);
 148:  
 149:             /*設定委派處理函式*/
 150:             mSetUdpReceivedDlg = OnUdpReceivedText;
 151:  
 152:             //..啟動非同步接受資料
 153:             mSocketServer.BeginReceiveFrom(
 154:                 mRecvBuffer, 
 155:                 0, 
 156:                 mRecvBuffer.Length, 
 157:                 SocketFlags.None, 
 158:                 ref mRemotePoint, 
 159:                 new AsyncCallback(EndRecvCallBack), 
 160:                 mSocketServer
 161:               );
 162:         }
 163:  
 164:     }
 165:  
 166:     /// <summary>
 167:     /// 定義專用事件參數類別
 168:     /// </summary>
 169:     public class UdpEventArgs:EventArgs
 170:     {
 171:         private string mIP;
 172:         private Stream mMSG = new MemoryStream();
 173:  
 174:         public UdpEventArgs(Stream msg, string ip)
 175:         {
 176:             MSG = msg;
 177:             IP = ip;
 178:         }
 179:  
 180:         public string IP
 181:         {
 182:             get { return mIP; }
 183:             private set { mIP = value; }
 184:         }
 185:  
 186:         public Stream MSG
 187:         {
 188:             get { return mMSG; }
 189:             private set { mMSG = value; }
 190:         }
 191:     }
 192:  
 193:     
 194: }


使用該 Class


   1: int iPort = 5168;
   2: UDP_Server udpADAM;

啟動UDP封包接收伺服


   1: udpADAM = new UDP_Server(this, iPort);    // 建立物件
   2: udpADAM.UdpReceived += onUdpReceived;    // 串接事件

事件程式


   1: #region UDP Server 事件 
   2: private void onUdpReceived(object sender, UdpEventArgs e)
   3: {
   4:    
   5:     byte[] bytes = UDP_Server.StreamToBytes(e.MSG);
   6:     // .....
   7: }

沒有留言:

張貼留言