/// <summary> /// Starts UDP server. /// </summary> public void Start() { if (m_IsRunning) { return; } m_IsRunning = true; m_StartTime = DateTime.Now; m_pDataReceivers = new List <UDP_DataReceiver>(); // Run only if we have some listening point. if (m_pBindings != null) { // We must replace IPAddress.Any to all available IPs, otherwise it's impossible to send // reply back to UDP packet sender on same local EP where packet received. This is very // important when clients are behind NAT. List <IPEndPoint> listeningEPs = new List <IPEndPoint>(); foreach (IPEndPoint ep in m_pBindings) { if (ep.Address.Equals(IPAddress.Any)) { // Add localhost. IPEndPoint epLocalhost = new IPEndPoint(IPAddress.Loopback, ep.Port); if (!listeningEPs.Contains(epLocalhost)) { listeningEPs.Add(epLocalhost); } // Add all host IPs. foreach (IPAddress ip in System.Net.Dns.GetHostAddresses("")) { IPEndPoint epNew = new IPEndPoint(ip, ep.Port); if (!listeningEPs.Contains(epNew)) { listeningEPs.Add(epNew); } } } else { if (!listeningEPs.Contains(ep)) { listeningEPs.Add(ep); } } } uint IOC_IN = 0x80000000; uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; // Create sockets. m_pSockets = new List <Socket>(); foreach (IPEndPoint ep in listeningEPs) { try{ Socket socket = Net_Utils.CreateSocket(ep, ProtocolType.Udp); // To avoid : "An existing connection was forcibly closed by the remote host" socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); m_pSockets.Add(socket); // Create UDP data receivers. for (int i = 0; i < m_ReceiversPerSocket; i++) { UDP_DataReceiver receiver = new UDP_DataReceiver(socket); receiver.PacketReceived += delegate(object s, UDP_e_PacketReceived e){ try{ ProcessUdpPacket(e); } catch (Exception x) { OnError(x); } }; receiver.Error += delegate(object s, ExceptionEventArgs e){ OnError(e.Exception); }; m_pDataReceivers.Add(receiver); receiver.Start(); } } catch (Exception x) { OnError(x); } } // Create round-robin send sockets. NOTE: We must skip localhost, it can't be used // for sending out of server. m_pSendSocketsIPv4 = new CircleCollection <Socket>(); m_pSendSocketsIPv6 = new CircleCollection <Socket>(); foreach (Socket socket in m_pSockets) { if (((IPEndPoint)socket.LocalEndPoint).AddressFamily == AddressFamily.InterNetwork) { if (!((IPEndPoint)socket.LocalEndPoint).Address.Equals(IPAddress.Loopback)) { m_pSendSocketsIPv4.Add(socket); } } else if (((IPEndPoint)socket.LocalEndPoint).AddressFamily == AddressFamily.InterNetworkV6) { m_pSendSocketsIPv6.Add(socket); } } } }
/// <summary> /// Starts UDP server. /// </summary> public void Start() { if(m_IsRunning){ return; } m_IsRunning = true; m_StartTime = DateTime.Now; m_pDataReceivers = new List<UDP_DataReceiver>(); // Run only if we have some listening point. if(m_pBindings != null){ // We must replace IPAddress.Any to all available IPs, otherwise it's impossible to send // reply back to UDP packet sender on same local EP where packet received. This is very // important when clients are behind NAT. List<IPEndPoint> listeningEPs = new List<IPEndPoint>(); foreach(IPEndPoint ep in m_pBindings){ if(ep.Address.Equals(IPAddress.Any)){ // Add localhost. IPEndPoint epLocalhost = new IPEndPoint(IPAddress.Loopback,ep.Port); if(!listeningEPs.Contains(epLocalhost)){ listeningEPs.Add(epLocalhost); } // Add all host IPs. foreach(IPAddress ip in System.Net.Dns.GetHostAddresses("")){ IPEndPoint epNew = new IPEndPoint(ip,ep.Port); if(!listeningEPs.Contains(epNew)){ listeningEPs.Add(epNew); } } } else{ if(!listeningEPs.Contains(ep)){ listeningEPs.Add(ep); } } } uint IOC_IN = 0x80000000; uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; // Create sockets. m_pSockets = new List<Socket>(); foreach(IPEndPoint ep in listeningEPs){ try{ Socket socket = Net_Utils.CreateSocket(ep,ProtocolType.Udp); // To avoid : "An existing connection was forcibly closed by the remote host" socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); m_pSockets.Add(socket); // Create UDP data receivers. for(int i=0;i<m_ReceiversPerSocket;i++){ UDP_DataReceiver receiver = new UDP_DataReceiver(socket); receiver.PacketReceived += delegate(object s,UDP_e_PacketReceived e){ try{ ProcessUdpPacket(e); } catch(Exception x){ OnError(x); } }; receiver.Error += delegate(object s,ExceptionEventArgs e){ OnError(e.Exception); }; m_pDataReceivers.Add(receiver); receiver.Start(); } } catch(Exception x){ OnError(x); } } // Create round-robin send sockets. NOTE: We must skip localhost, it can't be used // for sending out of server. m_pSendSocketsIPv4 = new CircleCollection<Socket>(); m_pSendSocketsIPv6 = new CircleCollection<Socket>(); foreach(Socket socket in m_pSockets){ if(((IPEndPoint)socket.LocalEndPoint).AddressFamily == AddressFamily.InterNetwork){ if(!((IPEndPoint)socket.LocalEndPoint).Address.Equals(IPAddress.Loopback)){ m_pSendSocketsIPv4.Add(socket); } } else if(((IPEndPoint)socket.LocalEndPoint).AddressFamily == AddressFamily.InterNetworkV6){ m_pSendSocketsIPv6.Add(socket); } } } }