2010-04-07 6 views
-1

다음 코드 조각은 4-5 스레드로 병렬 때 잘 실행하지만, 스레드의 수가 10 개 동시 스레드Socket.Recieve 실패하면 멀티 스레드

int totalRecieved = 0; 
int recieved; 
StringBuilder contentSB = new StringBuilder(4000); 
while ((recieved = socket.Receive(buffer, SocketFlags.None)) > 0) 
{ 
    contentSB.Append(Encoding.ASCII.GetString(buffer, 0, recieved)); 
    totalRecieved += recieved; 
} 

Recieve 메소드가 리턴을 넘어 어딘가에 증가로 실패하기 시작 읽은 바이트가 0 인 상태에서 계속 메소드를 호출하면 예외가 발생합니다. '설정된 연결이 호스트 시스템의 소프트웨어에 의해 중단되었습니다'. 따라서 호스트가 실제로 데이터를 보낸 다음 연결을 닫은 것으로 가정합니다. 그러나 어떤 이유로 그것을받지 못했습니다.

많은 스레드가있을 때 왜이 문제가 발생하는지 궁금합니다. 나는 그것이 각 스레드가 많은 실행 시간을 얻지 못하며 따라서이 오류를 일으키는 스레드에 대한 유휴 시간이 있다는 사실과 관련이 있다고 생각하고있다. 유휴 시간으로 인해 소켓에서 데이터를받지 못하는 이유를 알 수 없습니다.

편집 : 설명하기 만하면됩니다. 각 스레드는 다른 데이터를 읽는 자체 소켓을 가지고 있습니다.

+0

각 스레드는 자체 소켓을 가지고 있습니다. –

+0

스레드 하나당 하나의 소켓을 읽거나 스레드 당 하나의 소켓을 읽는 스레드가 많은 경우 분명하지 않습니다. – ParmesanCodice

+0

SocketError 코드 (SocketException.ErrorCode)를 알고 계십니까? 시간 초과 될 수 ... – ParmesanCodice

답변

0

문제는 여러 스레드의 동일한 소켓에서 수신을 사용하려고 시도하는 중입니다.

Socket class에 대한 MSDN 설명서는 소켓의 Receive 메서드가 실행 중 단일 스레드 한 스레드에서만 사용되도록 특별히 권장합니다.

  • 사용 BeginReceiveEndReceive, MSDN 추천, 또는

  • 사용으로 단일 소켓 : 당신이해야 하나 같은 소켓에서 데이터를 읽기 위해 여러 스레드를 필요로하는 응용 프로그램에 대한

    패킷을 수신하기 위해 스레드를 읽은 다음 각각의 패킷을 동기화 된 대기열에 씁니다. 그런 다음 여러 스레드가 큐에서 데이터를 가져올 수 있습니다.

+0

좋은 지적. 비동기 방식으로 변경하겠습니다. 왜 동기화 접근이 실패할지 이해하지 못합니다. –

+0

MSDN은 특히 두 개 이상의 스레드와 통신을 처리하는 '수신'을 사용하면 안된다고 명시합니다. 쓰래드의 실행은 비 결정적이기 때문에, 그 구현은 아마도 4 개 미만의 쓰레드만으로도 올바르게 작동 할 것입니다. –

+3

MSDN 문구는 다소 혼란 스럽다. 다중 스레드가있을 때'Receive'를 사용하는 것은 문제가되지 않는다. 문제는 여러 스레드의 동일한 소켓에서 Receive를 사용하려고 시도하는 것입니다. 각 스레드가 다른 소켓을 처리하는 경우 두 개의 다른 스레드에서이 문제를 사용할 때 아무런 문제가 없습니다. –

1

오픈 연결에 대한 시스템 제한이 있습니다 (시작 번호는 this SO question 참조). 여기에 more info이 있습니다.

+0

@Qua는 Socket 객체의 작성 방법을 보여주지 않았으므로 그러한 제한이 발생할 수 있습니다. –

+1

허용 된 대답이 잘못되어 해당 질문에 대한 새 답변을 추가했습니다. 라이선스 부과 된 한도 인 10은 MS가 제공 한 응용 프로그램 프로토콜에만 적용됩니다. 10 가지 이유가 있습니다. 다른 링크가 더 좋으므로 (예 : 10 개 미만의 반 TCP 연결, 1 초 이내에 10 개의 새 연결 없음). –

+0

@ 케빈 : 나는 이것에 대해 더 나은 Q + A를 알고 있지만 찾을 수는 없습니다.) - : –