2013-04-27 3 views
0

. NETMF 응용 프로그램에 UDP 서버가 있습니다.이 솔루션은 UdpClient와 같은 클래스와 메서드가없는 것을 제외하면 고전 .NET Framework 4.5와 유사합니다.C# UDP 다수의 클라이언트

_server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
_server.Bind(ep); 

을 그리고 지금은 여러 스레드에서 데이터를 받아 (모든 IPEndPoint로 하나 개의 스레드) 할 :이 같은 소켓에 "듣기 시작". 요점은 속도를 극대화하는 것입니다. (UDN 클라이언트 클래스를 사용할 수 없도록 .NETMF를 사용하고 있습니다.)

두 가지 아이디어가 있습니다. 먼저 각각의 스레드에 대해 IPEndPoint을 만들고 거기에서 데이터를 수락/처리했습니다. 그러나 문제는 스레드가 데이터를 받아들이고 받아 들인 소스 IP/포트가이 스레드에 할당 된 IP/포트와 다르다는 것을 결정한 후이 데이터가 버리고 다른 적절한 스레드에 더 이상 사용할 수 없다는 것입니다. 그것을 고칠 수있는 간단한 방법이 있습니까? 아래 예제 코드를 참조하십시오.

using System; 
using Microsoft.SPOT; 
using System.Net; 
using System.Net.Sockets; 
using System.Threading; 

namespace MFConsoleApplication1 
{ 
    internal class ServerThread 
    { 
     internal IPEndPoint EP { get; private set; } 
     internal Socket Server { get; private set; } 
     public ServerThread(IPEndPoint ep, Socket s) 
     { 
      EP = ep; 
      Server = s; 
      new Thread(() => 
      { 
       byte[] buffer = new byte[2048]; 
       int byteCount; 
       EndPoint recvEP = new IPEndPoint(IPAddress.Any, 0); 
       while (true) 
       { 
        byteCount = Server.ReceiveFrom(buffer, ref recvEP); 
        if (!recvEP.Equals(EP)) cotinue; //this makes the thread to ignore 
        // to ignore the data as EP is different,but it throw the data away 

        // Process data 
        Debug.Print(byteCount.ToString()); // For example 
       } 
      }).Start(); 
     } 
    } 
} 

다른 아이디어는 데이터를 받아들이는 하나의 스레드를 갖는 것입니다. 데이터 청크가 소스 IP/포트를 기반으로 받아 들여지면이 스레드는 새로운 스레드를 만들어 데이터를 처리합니다. 이렇게하면 초당 수십 또는 수백 개의 스레드를 생성해야하므로 너무 우아하지는 않습니다. 약간의 영향은 각 예상 IPEndPoint에 대한 스레드를 생성하고 특정 끝점에 대한 데이터를 사용할 수있을 때까지 일시 중단 된 상태로 유지하는 것입니다.

이 문제의 해결책은 무엇입니까?

아무쪼록 고맙습니다.

업데이트 는 자연적인 방법은 다음과 같습니다

_server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
_server.Bind(ep); 
while (true) 
{ 
    byteCount = Server.ReceiveFrom(buffer, ref recvEP); 
    // Process data 
    Debug.Print(byteCount.ToString()); // For example 
} 

내가 보낸 사람의 주소를 기초로 데이터를 처리해야하지만. 그래서 아마도 같은 유사한 의미로 라인을 추가 할 수 있습니다

new Thread(new ParameterizedThreadStart(ProcessData)).Start(recvEP); 

일부 데이터를 수신 후 매번 실행하지만 서버가 수십 수신으로 - 초당 메시지의 수백이 중 하나를 너무 우아 woudn't .

제 문제에 대한 최적의 해결책을 제안하십시오.

+0

이 질문은 귀하가 보여준 코드에서 의미가 없습니다. 서버가 있지만 클라이언트라고합니다.또한 데이터가 버퍼로 들어갑니다. 왜 거기에서 액세스 할 수 없습니까? 명확히하십시오. – theMayer

+0

또한 코드의 _all_입니까? – theMayer

+0

Fez 또는 Netduino를 사용하는 기기는 무엇입니까? –

답변

1

먼저 끼워 넣기 작업을 할 때 : 작업을 처리하기 위해 스레드를 생성하지 마십시오. 대기열 데이터 구조를 사용하고 요청에 응답 할 수있는 충분한 정보를 저장하십시오 (즉, 정보를 정리하십시오). IO를 수행하는 스레드와 응답을 처리하는 스레드를 사용하십시오. 첫 번째 메시지가 대기열에 메시지를 넣을 지 결정합니다. 만약 당신이하지 않고 요청이 들어올 때마다 스레드를 생성하면 패킷 범람과 다른 DoS 공격에 취약해질 것입니다. 그것은 당신의 제한된 기억을 먹을 것입니다. 큐에 합당한 수 이상의 패키지가있는 경우 패키지 수락을 중지하십시오.

대기열에서 처리 할 패키지가있을 때 두 번째 스레드를 깨우도록하십시오. 다른 대기열 (보내는 메일과 같은)에서 보낼 응답을 준비합니다. 대기열에 더 이상 항목이 없으면 잠자기 상태가됩니다.

작업량이 많은 컴퓨팅 인 경우 런타임로드 가능 프로 시저를 사용하여 작업 속도를 높입니다.