2015-01-29 1 views
0

바이트 배열에 대한 buffer_size를 명령 줄 인수로 사용하고 파일을 읽고 서버에 전송할 바이트 배열을 선언하는 Java 클라이언트를 작성했습니다. 덩어리. 클라이언트는 파일 읽기를 시작하기 전에 buffer_size를 java 서버로 전송하여 서버가 파일 청크를 수신 할 바이트 배열을 정의 할 수도 있습니다.Java 클라이언트에서 서버로 청크 파일 보내기

while ((count = fileReader.read(bytes)) > 0) { 
    toServer.write(bytes, 0, count); 
} 

서버 측 :

while ((count = fromClient.read(bytes)) > 0) { 
    //process the received file content 
} 

이 나를 위해 잘 작동 그래서이 메커니즘은

클라이언트 측 .... 같이 보입니다. 그러나 청크를 읽는 서버의 동작은 무작위로 바뀝니다. 즉, 클라이언트가 읽을 파일이 3000 바이트이고 buffer_size가 8192 바이트 인 경우 (서버의 buffer_size가 8192이기도 함) 서버는 전체 읽기 (클라이언트에서)를 단일 읽기로 읽습니다() 작업을 수행하고 경우에 따라 청크를 2 부분으로 나누고 읽기 (2 개의 read() 작업을 수행하는 2 개의 1500 바이트로). 나는 정확히 여기서 무슨 일이 일어나는 지 이해하지 못한다. 서버가 클라이언트에 의해 보내지는 청크를 분할하지 않도록 이것을 구현할 수 있습니까?!

로컬 컴퓨터에서 클라이언트와 서버를 모두 실행하여 테스트 할 때 서버는 단 하나의 read() 작업으로 하나의 write() 작업을 사용하여 클라이언트가 보낸 전체 콘텐츠를 읽습니다. 동작 변경은 클라이언트와 서버가 서로 다른 시스템에있는 경우에만 발생합니다.

답변

0

1500은 아마도 링크의 MTU입니다. 데이터는 전송되는 크기의 패킷으로 분할됩니다. 서버를 구현할 때 데이터가 임의 크기의 패킷으로 분할 될 준비가되어 있어야합니다.

TCP로 구현 된 추상화는 일련의 write() 호출이 아닌 바이트 스트림입니다. 특정 패킷 크기를 강제로 사용하려면 UDP를 사용해야하며 UDP는 전달을 보장하지 않으므로 패킷 손실을 처리해야합니다.

이 문제를 해결하려면 전체 버퍼를 읽거나 파일 길이에 도달 할 때까지 루프를 읽으십시오. 클라이언트는 프로토콜의 시작 부분에서 파일의 길이를 간단히 보낼 수 있습니다. 클라이언트와 서버가 동일한 버퍼 크기를 사용할 필요가 없습니다.

+0

그런데 같은 호스트에서 다르게 작동하는 이유는 로컬 호스트의 경우 MTU가 훨씬 더 커진다는 것입니다. 그러나 그것은 무제한이 아닙니다. 64KiB 이상을 쓰려고하면 localhost 인터페이스 이상으로 나뉘어진다. – Atsby

+0

그래, 그것을 가지고 내 코드도 수정. 그러나 서버에서 읽히는 청크는 이더넷을 통해 전송되는 동안 항상 1500 바이트 이하로 유지되지는 않습니다. – Sudershan

관련 문제