2008-10-01 8 views
3

(.NET 비동기) TCP 서버에 많은 양의 메시지를 보내는 .NET TCP 클라이언트가 있습니다.대용량 TCP 클라이언트 설계

TIME_WAIT (으)로 인해 서버에 메시지를 계속 보내야하지만 클라이언트의 포트가 부족합니다.

사용 가능한 모든 포트를 사용하지 않고도 프로그램이 메시지를 지속적으로 안정적으로 보낼 수있는 방법은 무엇입니까?

동일한 소켓을 계속 재사용 할 수있는 방법이 있습니까? Disconnect()와 REUSEADDRESS 소켓 플래그를 살펴 보았지만 좋은 사용 예제는 찾을 수 없습니다. 실제로 대부분의 소식통은 낮은 수준의 사용 (즉, 소켓 핸들 만 재활용)과 같이 Disconnect를 사용하지 말라고 말합니다.

나는 UDP로 전환해야한다고 생각하거나 아마도 C++과 IOCP를 사용하는 방법이 있을까요?

답변

1

클라이언트가 동일한 소켓을 열어두고 루프에서 메시지를 보낼 수 있습니까?

open socket connection 

while(running) 
    send messages over socket 

close socket connection 
0

코딩 된 경우 작동하지 않습니다.

서버는 첫 번째 메시지 만 수신합니다.

소켓을 열었다 닫으면 서버가 작동하지만 클라이언트 포트가 부족합니다.

저는 클라이언트를 그렇게 코딩해야하는 원인이되는 서버의 설계를 추측합니다.

그렇다면 .NET을 사용하여 비동기 서버를 코딩하는 방법은 무엇입니까? MSDN 예제와 수많은 예제를 온라인에서 따라 왔습니다.

0

메시지 대기열 서비스의 어떤 것이 프로젝트에 도움이됩니까? 그렇게하면 클라이언트가 서버에 많은 메시지를 전달할 수 있고 서버가 대기열에서 메시지를 가져올 수 있고 가능한 한 빨리 처리 할 수 ​​있으며 클라이언트가 처리 할 수있는 것보다 많은 양을 보내는 경우 간단합니다 대기열을 입력하고 처리 대기.

일부 빠른 인터넷 검색 결과는 MSDN documentation on building a message queuing service with C#입니다.

0

TCP 서버 작성 (모든 언어)의 기본 개념은 하나의 포트를 열어 연결을 수신 한 다음 새로운 연결 요청을 처리 할 새 스레드 또는 프로세스를 만드는 것입니다.

open a server socket // this uses the port the clients know about 

while(running) 
    client_socket = server_socket.listen 
    fork(new handler_object(client_socket)) 

여기는 a good example in C#입니다.

+0

이 척도가 너무 심각하지 않습니까? 1000 개의 연결이 있다고 가정합니다. 1000 개의 스레드가 있어야한다고 제안합니까? – Arafangion

+0

@Arafangion : 많은 동시 연결이 예상된다면 스레드 풀링을 사용할 수 있습니다. 이는 응용 프로그램에 대해 언제든지 활성화 될 스레드 수에 대한 상한을 설정하고 사용을 관리하는 데 도움이됩니다. –

+0

select() 또는 다른 폴링에 비해 불필요한 오버 헤드가 여전히 높습니다. – Arafangion

5

서버와 클라이언트가 데이터의 형식을 알고 있으면 소켓을 열린 상태로 유지할 수 있습니다. 서버가 클라이언트가 "완료되었음을"알 수 있도록 소켓을 닫고 있습니다.

일부 프로토콜을 사용하는 경우 서버는 데이터 블록 수신이 완료되면 "알 수 있습니다".

somekind의 End of Message 토큰을 찾고, 메시지 길이를 전달하고, 크기 등을 기준으로 나머지를 읽을 수 있습니다. 다른 방법.

하지만 서버에 대한 연결을 끊고 열어 볼 필요가 없습니다. 그게 바로 당신을 죽이는 이유입니다.

1

TCP는 네트워크의 정체를 방지하기 위해 매우 열심히 노력합니다.모든 새로운 TCP 연결은 "느린 시작"상태에서 시작합니다.이 상태에서는 하나의 패킷 만 보내고 다른 쪽 끝에서 확인 응답을 기다립니다. ACK가 수신되면 TCP는 최대 창 크기에 도달 할 때까지 두 개의 패킷을 보낸 다음 네 개의 패킷을 전송합니다.

높은 데이터에서 메시지를 생성하는 경우에는 TCP 연결을 열거 나 닫지 않는 것이 좋습니다. 새로운 연결을 열 때마다 천천히 시작합니다. 소켓을 열어 둘 수 있으면 TCP 연결은 느린 시작 상태를지나 훨씬 더 높은 속도로 데이터를 보낼 수 있습니다.

이렇게하려면 서버가 연결에서 둘 이상의 메시지를 처리하도록해야합니다. 즉, 각 메시지의 윤곽을 그리는 방법을 찾는 것입니다. 서버가 어떤 종류의 HTTP 인코딩도 지원한다면 이것이 가능할 것입니다. "지속적인"연결 또는 HTTP 1.1과 관련된 인수 또는 구성은 HTTP가 단일 TCP 연결을 통해 여러 요청을 보내는 방법이기 때문에 검사해야합니다.

언급 한 옵션 중 하나가 UDP입니다. 합리적으로 높은 비율로 메시지를 생성하는 경우 대기열이 어딘가에 가득 차 있기 때문에 메시지를 잃을 가능성이 큽니다. 보내는 메시지가 신뢰할 수 있어야 할 경우 UDP가 좋은 근거가 아닐 수 있습니다.