2010-12-10 8 views
1

Java 응용 프로그램 (NIO 사용)을 C 소켓으로 변환 중이며 문제가 발생했습니다. 동시에, 나는 TCPProxy로서 그라인더를 사용하여 무엇이 전송되었는지 확인하고있다.소켓 - C와 Java 전송의 차이점

핸드 셰이크의 일부로 클라이언트에 보낼 필요가있는 4 줄이 있습니다.

Hello~Server\r\n 
Hello1~Server1\r\n 
Hello2~Server2\r\n 
Hello3~Server3\r\n 

Java 응용 프로그램 (NIO 사용)의 경우 각 Java NIO flip() 후에 각 문자열이 전송되었습니다. 즉 위의 4 줄이 한 번에 하나씩 발송됩니다.

Java 용 의사 코드가 있습니다.

  1. 지우기 버퍼, 버퍼에
  2. 넣어 문자열, 문자열의
  3. 넣어 크기,
  4. 플립.

C 소켓의 경우 4 개의 별도 send()가 있어도 4 개의 char 배열이 함께 전송되었습니다.

Stumped. 어떤 아이디어?

+0

당신은 독수리가 있고 모든 유착은 꺼져 있습니까? –

+0

피터 안녕하세요. 나는 독수리에 대해 읽고 있었지만 나는 아직 그것을 해제하지 않았다. 나는 그것을 시도 할 것이다. 감사합니다. – Poliquin

답변

3

TCP는 스트림 지향 프로토콜입니다. 즉, 스트림이 어떻게 분리되는지는 중요하지 않습니다. 따라서 특정 경계에서 스트림을 분할해야하는 디자인은 아마도 TCP를 잘못 사용했을 것입니다.

그렇다면 TCP_NODELAY 옵션을 사용하여 setsockopt을 통해 '일괄 처리'를 시도 할 수 있습니다.

+0

감사합니다. lijie, 나는 그것을 시도 할 것입니다. – Poliquin

1

C 코드에서 보낸 메시지는 아마도 Nagle's algorithm에 의해 단일 패킷으로 병합되고 있습니다. Nagle의 알고리즘을 비활성화하려면 소켓 의 setting the TCP_NODELAY option으로이를 비활성화 할 수 있습니다. 그러나 TCP는 메시지 경계를 존중할 필요가 없다는 것을 명심해야한다. 그래서 프로토콜은 send()와 send() 사이의 1-1 대응에 의존하기보다는 완전한 메시지가 수신 된 때를 결정하는 독자적인 방법을 가져야한다. recv() 호출.

+0

짐, 머리를 가져 주셔서 감사합니다. 나는 당신의 말을 염두에 두겠다. 신속한 답변에 다시 한 번 감사드립니다! 말하자면, 어느 누구도 Java nio가 Nagle의 고아를 사용할 수 없게할지 여부를 알 수 있습니까? – Poliquin

0

나에게 제안 할 시간을 가져 주셔서 감사합니다 (느린 것). 나는 TCP_NODELAY를 활성화 시키려고했지만 '문제'를 수정하지는 못했다. 내가 '문제'라고 말한 이유는 무엇입니까?

내 send()를보고 strlen (메시지) 대신 sizeof (메시지)를 사용함을 알았습니다. sizeof() - 보낼 바이트 크기를 가져옵니다. strlen() - \ 0을 제외한 보낼 문자 수를 얻습니다.

나는 우분투의 맨 페이지가 말한 바를 따르기에 순진했다.

yakult121의 $ 남자 (* 버퍼, 렌 size_t가, 플래그를 int로 INT의 sockfd와, CONST 무효)

ssize_t의 전송을 보내;

size_t len은 memset()에 사용 된 것처럼 sizeof()를 사용하기위한 것이라고 생각했습니다.

yakult121 $ 남자가 memset

* memset 함수 보이드 (공극 * S, INT C를이 size_t 않음);

마침내 socklen_t와 size_t는 다른 데이터 유형이라는 것을 알았습니다.

다시 한번 감사드립니다. 나는 문제를 발견하지 못했고 계속 Nagle의 골목을 가리킬 것이다.

+0

실제로'sizeof'는 컴파일 타임의 것입니다 : 그것은 표현식이나 타입에 의해 차지 된 문자의 수로 평가됩니다. 'size_t' 타입의 것을 만들 필요가있을 때 자동으로'sizeof'를 사용하지 마십시오 - 당신이하고 싶은 것을 생각할 필요가 있습니다. – lijie

+0

흠 size_t는 무엇을합니까? – Poliquin