안녕하십니까..
클라이언트 소켓프로그램을 짜고 있는데(Indy가 아닌), 서버에서 데이타를 받아오려고 합니다..
그 데이타 양이 65536바이트를 보낸다면,
클라이언트가 한번에 이 양을 다 받을 수도 있겠지만, 망이 안좋아은 경우 몇번에 걸쳐 나누어 받는 경우도 있는 것으로 알고 있습니다.
그래서 버퍼사이즈를 65536으로 하고,Socket1Read이벤트가 발생했을때 데이타 사이즈를 체크해보고 나서 65536바이트가 아니라면 다시 기다려야되는걸루 알고 있습니다.
그렇다면 예를 들어 체크했을때 30000바이트였다면, 어떻게 처리를 해줘야 계속해서 기다리게 되나요? 그리고 운이 좋아서 다음에 받은게 나머지
35536이었다면 이 35536은 알아서 버퍼의 뒤쪽을 채워줍니까,아님 프로그래머가 위치를 지정해주어야합니까..
무슨 뜻인지는 아시겠죠? ^^ 워낙 두서가 없어서리..
그리고 TCP에서 한번에 전송할 수 있는 데이타 사이즈는 최대 몇 바이트 인지요..
부탁드립니다..소켓프로그램은 그 동안 몇 번짰었는데 다 짤막한 것만 해서 별 신경을 안 썼는데 이번은 좀 경우가 다르네요..도와주세요.~~
TCP 전송의 경우 최대 1460 바이트가 전송됩니다.
그렇다고 무조건 1460을 채우는 것은 아닙니다.
가령 65535 바이트를 한방에 전송한다면 1460 씩 한 10번 나오고 220 바이트가 나왔다
다시 1460바이트씩 전송되기도 합니다. 그것은 클라이언트에서 버퍼를 읽는
속도와 관련이 있겠지요... 그러므로 일정한 패킷크기로 잘라서 보내면
각각의 패킷을 버퍼링 하므로 버퍼링 속도가 양호해 져서 원하는 패킷사이즈
가 날라갈겁니다.
그냥 소켓으로 무작정 파일을 한방에 전송하면 클라이언트 모듈은 간단해 집니다만
서버쪽 모듈 (혹은 받는 클라이언트 쪽)은 무척 난감합니다. 통신망의 상태에
따라서 나중에 보낸 패킷이 먼저 도착하기도 하기때문입니다. 그렇기 때문에
어떤 프로토콜을 정의해야 합니다.
예를 들자면
TmyProtocolPacket = record
FileID : String[20]; // unique 한 값을 만들어 줘야 하죠...
PacketNo : Integer; // 지금 보낸 패킷이 몇번째 인가
Length : Integer; // 이번 날라온 넘의 유효 크기
TotalPacket : Integer; // 전체 패킷은 몇개가 될건가
Body : Array [1..256] of Byte ; // 실제 바디
end;
물론 이 패킷을 보내기 전에 앞으로 파일을 보낼 작정인데 파일명은 뭐고
사이즈는 얼마다 하는 정보를 먼저 보내주는 것이 좋습니다. 위의 패킷에
추가해도 되지만 쓸데없이 중복된 내용을 보낼 필요는 없지요...
보내는 놈은 파일을 잘라서 바디에 복사해서 보내면 되고,
받는 넘은 ReceiveThread에서 OnRecieve Event 발생시에
처음에 파일정보를 받고 메모리를 할당하거나 파일스트림을 열어놓고
파일 내용이 날라오면 받을때 마다 해당 위치에다가 Write해주면 되지요..
도움이 되었기를 바랍니다.
-- 지도 잘 모르는 넘