2012-01-11 3 views
2

C# UdpClient 클래스를 사용하여 UDP 네트워킹을 사용하고 있습니다. 하나의 UdpClient 오브젝트가 고정 로컬 포트에 바인드되지만, 다른 엔드 포인트와주고받을 수 있어야하므로 원격 엔드 포인트에는 바인드되지 않습니다.잘못된 스레드에서 SocketException이 발생했습니다.

두 개의 스레드가 있습니다. 하나는 송신 용이고 하나는 수신 용입니다. 이제 존재하는 끝점에 데이터를 보내지 만 해당 포트에서 수신 대기하지 않으면 SocketException이 필요합니다. 그리고 나는 하나를 얻는다. 불행히도 예외를 반환하는 것은 내 Send 호출이 아니지만 Receive 호출입니다. 그래서 내 보내는 스레드에서 데이터를 "유효하지 않은"끝점에 보내고받는 스레드가 예외를 가져옵니다. 불행히도, 그 시점에서, 나는 끝 점이 예외를 발생시키는 원인을 전혀 모릅니다.

보내기 전에 끝점을 저장하면받는 스레드에서 해당 끝점에 액세스하는 것은 대기 상태의 경쟁 조건 오류 일뿐입니다.

불행히도 SocketException은 오류를 발생시킨 끝점을 제공하지 않습니다.

아이디어가 있으십니까? 어떻게 든 예외를 보내는 스레드에서 throw 할 수 있습니까?

도움을 주시면 대단히 감사하겠습니다.

+0

UDP가 작동하는 방식 때문에 설계 상 다소 차이가 있다고 생각합니다. 그것이 데이터를 송신 할 수 있다고 가정하면, 즉 정확하게 초기화된다.나는 UDP가 어떤 에러 검사도하지 않기 때문에 이것을 믿는다. 그것은 단순한 보냄과 잊어 버림. –

+0

Receive() 호출을 죽이지 않으면 살 수 있습니다. 여하튼, 이것은 꽤 비논리적 인 것처럼 보인다. –

+0

문서에 더 가까운 독자라면 다른 것일 수도 있습니다. 당신을 더 잘 돕기 위해 SocketException과 SocketException.ErrorCode를 게시 할 수 있습니까? –

답변

3

send() UDP 패킷은 유선에 나가 효과적으로 사라집니다. 당신은 당신이 전혀 피드백을받을 것이라고 가정해서는 안됩니다.

수신자에 수신자가없는 경우 수신자 일 때 ICMP_UNREACH_PORT 메시지를 보낼 정도로 친절 할 수 있습니다. 그 사이의 라우터는 일 수 있고은 운영 체제에 메시지를 전달하기에 충분할 수 있습니다. 이 경우 원래 send() 전화가 반환 된 후에도 오래있을 것입니다. ICMP_UNREACH_PORT의 경우 OS가 일반적으로 캐시하고 다음 번에 같은 대상에 send()을 수행 할 때 오류를보고합니다. 다른 ICMP 메시지 (어떤 예외가 발생했는지 언급하지 않았 음)는 다른 호출에 영향을 미칠 수 있습니다.

따라서 결론은 UDP 오류가보고 될 때 또는 알려지지 않는 경우입니다. 그것은 많은 변수에 달려 있습니다. 따라서 모든 호출에 대해 예외를 처리 할 준비를하고 오류가보고되지 않고 패킷이 사라지도록 준비하십시오.

0

이것이 UDP의 예상되는 동작이라고 생각합니다. UDP send()은 차단 작업이 아니므로 잠재적 인 오류가 발생할 때까지 기다리지 않습니다. (닫힌 포트가있는 활성 호스트로 보낼 때 안정적으로 수신되는 오류 메시지에 의존 할 수는 없으며, 방화벽이 걸리고 속도가 제한되거나 정체로 인해 떨어질 수 있습니다.)

connect() UDP 소켓을 특정 원격 엔드 포인트에 연결할 수 있습니다.이 포트는 고유 한 포트 번호를 할당하고 OS가 다른 임의의 호스트에서 해당 엔드 포인트와 오류를 구분할 수있게합니다. 그러나 다시 말하지만 이러한 오류를 처리하는 기능에 의존해서는 안됩니다.

예외적으로 더 많은 정보가 없습니다. 이것은 .NET이 UDP 소켓을 처리하는 방식에서의 감독처럼 보입니다. documentation에 따르면 예외의 ErrorCode를 확인하고 error을 적절히 처리해야합니다. (경우에 따라 오류를 무시할 가능성이 있음)

관련 문제