TCP 통신에서 무조건 byte단위로 송수신을 해야 하나요?
글쓴이: 익명 사용자 / 작성시간: 목, 2019/09/19 - 2:04오전
TCP/IP 소켓 프로그래밍 입문자 입니다.
TCP의 특징 중 하나인 "경계가 없어 read, write에 의존하는 코드를 작성하면 절대 안된다." 라고 알고있는데요.
그런데 소켓 프로그래밍 책에서 대략 다음과 비슷한 코드가 있는데
// Server char cnt; read(fd, &cnt, 1); for(int i = 0; i < cnt; ++i) { read(client_fd, &temp, 1); } // Client char buf[4] = { 3, 1, 2, 3 }; write(fd, buf, 4);
이러한 코드가 있는데
혹시 위 서버의 cnt변수의 자료형이 char이라서 잘 작동 하는 코드 인가요?
다시 말해서
// Server int cnt; read(fd, &cnt, 4); // Client int value = 0x12345678; write(fd, &value, 4);
위 코드는 위험한 코드 일까요?
물론 5번 이상의 테스트에서 모두 잘 작동하지만
TCP 통신의 특징인 경계가 없으니
혹시나 클라이언트에서 value 변수의 상위 2바이트인 1234 까지만 전송 되었고 (운영체제의 상황 때문에)
그 뒤 나머지 하위 2바이트인 5678는 전송 버퍼에 들어 간 상황에서 늦게 전송 되었다고 치고
이러한 상황에서 서버는 value의 상위 2바이트인 1234만 전송 받고 서버 프로그램이 종료되고
나머지 하위 2바이트 5678은 그냥 사라질 수 있지 않을 까요?
만약 맞다면, 혹시 그러면 위같 0x12345678 값을 전송할 때
unsigned char buf[4] = { 0x12, 0x34, 0x56, 0x78 }; 이렇게 전송하고 또 서버에서 이것을 조합해서
int형 변수로 만드는 잡업을 해야 하는 건가요?
패키 최소 단위가 바이트 라고 알고있는데
그래서 첫번쨰 코드는 옳바른 코드이고 두번째 코드는 위험한 코드 일까요?
긴글 읽어주셔서 감사합니다.
Forums:
현재 TCP/IP 구현상 예제로 드신 정도는 문제가
현재 TCP/IP 구현상 예제로 드신 정도는 문제가 발생할 일이 거의 없습니다.
그러나 2000 바이트 한 번 write, 한 번 read한다면 문제가 발생하죠. 보내는 동안 어떤 네트워크에서는 MSS 값에 걸려서 쪼개어 보내질 수 있습니다.
이럴 때를 대비해서 보낸 것의 단위를 알 수 있는 다른 방법이 필요합니다.
---
http://coolengineer.com
첫째 코드도 아주 좋은 코드라고 말하긴 어려워
첫째 코드도 아주 좋은 코드라고 말하긴 어려워 보이는데요.
소켓에 대한 read가 항상 성공할 거라고 가정하고 있군요.
아마 온전한 프로그램을 만드는 데 필요한 내용을 가르치기 위한 중간 과정 같은 것이겠죠?
아무튼 원리는 맞습니다. tcp 통신에서는 상대방이 보낸 단위로 끊어서 받을 수 있을 것이라고 가정해선 안 됩니다.
인스턴트 메신저나 이메일처럼 편리하게 동작하지는 않는다는 것이죠. 그런 기능은 tcp보다 윗 레벨의 프로토콜에서 구현해야 합니다.
댓글 달기