2011-08-13 2 views
1


일부 기본 소켓 메시징을 수행하고 있습니다. 나는 잘 작동하는 루틴을 가지고 있지만 부하가 걸려있는 문제가 있습니다.루프에서 C# Socket.SendTo가 발생하면 SocketException이 발생합니다 (라우터에 따라 다름)

UDP를 사용하여 비 연결형 SendTo를 수행하여 기본적으로 ping과 같은 작업을 수행하여 LAN에있는 수신자가 있는지 확인합니다. 이상적으로는 브로드 캐스트 주소 만 사용 하겠지만 무선 라우터는 내 브로드 캐스트를 릴레이하지 않는 것 같습니다. 내 해결 방법은 서브넷의 모든 IP를 반복하고 각 데이터 그램을 각 IP로 보내는 것입니다. 다른 PC는 듣고 있으며 그들이 메시지를 받으면 답장을 보내고 피어스가 서로를 찾게합니다. 다음은 서브넷의 각 IP에 데이터 그램을 보내는 루프에있는 코드입니다. 서브넷 범위가 큰 경우

  string msgStr = "some message here..."; 
      byte[] sendbuf = Encoding.ASCII.GetBytes(msgStr); 

      Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
      socket.Blocking = true; 
      socket.SendTo(sendbuf, remoteEndPt); 
      //socket.Close(); 

이 작동하지만, 나는 결국 "잘못된 인수"를 의미하는 오류 코드 "10022"와 SocketException이를 얻을 것이다 255.255.0.0 (의미 ~ 60,000 IP를 통해 반복) 말한다. 이것은 ~ 10,000 정도 성공한 후에 발생하기 때문에이 오류가 발생하기 시작합니다. 또한, 직장에서 사용하는 라우터는이 라우터를 처리하고 아마도 고성능 라우터이지만, 저의 실험실에서는 저렴한 라우터가 오류를 발생시키는 라우터입니다.

SocketException을 잡은 후 대기 시간을두고 루프를 다시 시작하기 전에 일반적으로 복구하지만 결국 오류가 다시 발생합니다.

내가 무슨 일이 일어나고 있는지 라우터의 버퍼가 가득 차서 더 이상 데이터를 보낼 수 없다고 생각합니다. 직장에서 더 높은 품질의 제품은이를 처리 할 수 ​​있지만 싸구려 제품은 느리게 작동합니다. 그것은 그럴듯하게 들릴까요?

몇 가지 질문 : 비 연결 방식의 SendTo를 사용하는 경우

1), 내 소켓에 Close()를 호출해야합니까?

Close()를 호출 할 때 어떤 이점도 보지 못했지만 Close()를 호출하면 심각하게 내 반복 속도가 느려집니다 (많은 것을 느리게하기 때문에 위의 주석을 달았습니다). 이게 말이 돼?

2) 더 많은 데이터를 보내려고하기 전에 기다려야한다고 말할 수있는 방법이 있습니까? 내가 그 원인이 무엇인지 아직 모르는 예외를 잡는 것은 옳지 않은 것처럼 보입니다.

감사합니다, J.

답변

2

내가 그에만 라우터 확실하지 오전하지만 난 당신이 또한 OS의 일부 제한으로 실행되고 있는지 의심 ...

어떤 이유로 당신이 Socket 모든를 만드는 보낼 시간이야? 그냥 아마도마다 보내지와 함께 ... Socket에 다음 Close()Shutdown()과 전화를하는 것이 좋습니다

어쨌든 따라 http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx에 ... 재사용 그러나 모든 255 개 IP를 정도 ...

체크 아웃 UdpClient - 주석 당 - 그

EDIT 구현/쉽게 더 강력한 만들 수 :

당신이 이렇게 원하는 경우 cket 재사용 "캐시"... 예를 들어 이것은 특정 소켓이 256 번의 ​​검사마다 만 사용되도록합니다.

// build/fill your Socket-Queue for example in the con 
class SocketExample 
{ 
    Queue<Socket> a = new Queue<Socket>(); 
    SocketExample() 
    { 
     int ii = 0, C = 256; 
     for (ii = 0; ii < C; C++) 
     { 
      a.Enqueue (new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)); 
     } 
    } 

    // in your function you just dequeue a Socket and use it, 
    // after you are finished you enqueue it 
    void CheckNetIP (some parameters...) 
    { 
     Socket S = a.Dequeue(); 
     // do whatever you want to do... 
     // IF there is no exception 
     a.Enqueue(S); 
    } 
} 
+0

필자는 Shutdown이 Connected Sockets에 대한 것으로 알고 있는데, 제 경우에는 Connectionless를 사용하고 있습니다. 틀 렸으면 고쳐줘. UdpClient에 관해서도, 나는 동일한 결과로 그것을 시도했다. 나는 UdpClient가 내가 사용하고있는 소켓 구현을 둘러싼 편의성 래퍼 (wrapper)라고 생각한다. 그래서 UdpClient를 사용하여 차이를 만들지 않을 것이다. – JayDee

+0

사실'Shutdown'은 UDP에는 필요하지 않습니다.'Close'가 여전히 적용됩니다 ... 내 제안을 시도 했습니까? – Yahia

+0

내가 알기로 셧다운은 Connected Sockets에 대한 것이고, 제 경우에는 Connectionless를 사용하고 있습니다. UdpClient에 관해서도, 나는 동일한 결과로 그것을 시도했다. 나는 UdpClient가 내가 사용하고있는 소켓 구현을 둘러싼 편의성 래퍼 (wrapper)라고 생각한다. 틀 렸으면 고쳐줘! 나는 소켓 재사용이 올바른 접근 일 것이라고 동의한다. 나는 단지 1 소켓을 사용하여 그것을 테스트했고, 매번 재사용되었고, 느린 방법으로 작동을 멈추었다. 그래서 아마도 더 나은 재사용 전략이 답이 될 것입니다. 소켓 풀이나 재사용으로 좋은 샘플을 알고 있습니까? 감사! – JayDee

관련 문제