2010-02-23 4 views
4

다른 어댑터를 통해 연결된 두 개의 TCP 소켓이 내 프로그램에 의해 연결되는 Windows 프록시 프로그램을 개발 중입니다. 즉, 내 프로그램은 하나의 소켓에서 읽고 다른 소켓으로 쓰고 그 반대도 마찬가지입니다. 각 소켓은 자체 스레드에 의해 처리됩니다. 하나의 소켓이 데이터를 읽을 때 다른 소켓이 그것을 쓰기 위해 대기한다. 내가 가진 문제는 하나의 링크가 100Mb에서 실행되고 다른 링크가 10Mb에서 실행되는 경우입니다. 100Mb 링크의 데이터를 10Mb 링크에 기록하는 것보다 빠릅니다. 더 느린 연결 속도로 본질적으로 실행되도록 더 빠른 연결을 "느리게"할 수 있습니까? 빠른 링크를 느린 속도로 변경하는 것은 옵션이 아닙니다. - 고마워요Windows에서 TCP 연결을 어떻게 느리게 할 수 있습니까?

답변

8

읽고 쓰는 스레드간에 고정 길이 큐 을 만듭니다. 대기열이 가득 차면 대기열에서 차단하고 비어있을 때 대기열에서 제거합니다. 정규 세마포어 또는 뮤텍스/조건 변수가 작동해야합니다. 느린 스레드가 항상 사용되도록 대기열 크기로 재생하십시오.

6

이것이 문제가되는 경우 프로그램을 잘못 작성하는 것입니다.

10mbps 링크에 10mbps 이상을 넣을 수 없기 때문에 더 느린 링크에 쓰는 쓰레드는 쓰는 동안 차단이 시작됩니다. 따라서 쓰레드가 쓰기 버퍼와 같은 크기의 읽기 버퍼를 사용하는 한, 쓰레드는 10mbps 파이프를 빠져 나올만큼 빨리 데이터를 소비해야합니다. 원격 송신자가 10mbps 이상을 100mbps 파이프에 넣지 않도록하는 데 필요한 모든 흐름 제어는 TCP 프로토콜에 의해 자동으로 처리됩니다.

따라서 읽기 및 쓰기 버퍼가 해당 스레드 (또는 모든 스레드)의 크기가 같으면 문제가 발생하지 않아야합니다.

+0

흠, 읽기 및 쓰기가 동일한 스레드에서 수행되는 경우에만 작동한다고 생각합니다. –

+0

@ 니콜라이 왜? 버퍼 오버플로가 없으면 괜찮을 것입니다. –

+0

나는 이것이 버퍼를 할당하고 그것을 읽고 쓰레드를 위해 큐에 넣는다는 사실로부터 유래했다고 생각한다. 그런 다음이 과정을 반복하십시오. 쓰기 스레드는 버퍼를 대기열에서 빼내고, 쓰고, 해제합니다. – meg18019

4

데이터를 쓸 수 없으면 데이터 읽기를 중지하십시오.

100Mb/s 링크에서 프로그램으로 들어오는 바이트 대기열과 프로그램에서 10Mb/s 링크로 나가는 대기열이 있습니다. 보내는 큐가 가득 차면 100Mb/s 링크에서 클라이언트를 다시 스로틀로 들어오는 큐와 TCP에서 읽기를 중지하십시오.

독자와 작성자 사이에 내부 대기열을 사용하여이를 깔끔하게 구현할 수 있습니다.

0

비 블로킹을 수행하는 경우 select() 스타일 이벤트 루프가 있습니다. 보내는 데이터 대기열이 하드 코딩 된 최대 크기보다 작은 경우 FD_SET (readSocket, & readSet) 만 호출하십시오.

그런 식으로 나가는 소켓이 뒤쳐지면 프록시는 백업을 잡을 때까지 더 빠른 클라이언트에서 데이터 읽기를 중지합니다. TCP 프로토콜은 나머지 부분을 처리합니다 (특히 더 빠른 클라이언트에게 잠시 동안 속도 저하가 있음을 알려줍니다).

3

많은 복잡하고 정확한 해결책이 설명되었습니다. 그러나 정말로, 문제의 핵심에 도달하려면 - 왜 두 개의 스레드가 있습니까? socket-100을 읽은 경우, socket-10은 단일 스레드로 쓰고 자연스럽게 쓰기를 차단하므로 복잡한 작업을 할 필요가 없습니다.

관련 문제