데이터 전송
글쓴이: 익명 사용자 / 작성시간: 수, 2020/10/14 - 5:39오후
TCP 소켓 통신을 공부중입니다.
Linux Server - Windows Client
클라이언트에서 1Mbyte 데이터를 1k씩 1000번 보내고 서버에서 받으려고 하는데 질문이 있습니다.
1. 수신버퍼에 1000번 수신해 1k씩 누적해서 1Mbyte를 받을수 있는가?
이때 사용할 수 있는 함수는 어떤것인가?
2. 송신할때 1Mbyte의 버퍼를 어떻게 1k씩 잘라서 전부 송신하나?
이때 사용할 수 있는 함수는 어떤것인가?
read/write함수에 한계를 느껴 여러분께 도움을 요청합니다.
혹시나 제가 위 함수에 대해 부족한점이 있을 수 있으니 피드백 부탁드립니다.
Forums:
저도 잘은 모릅니다만, 덧글이 안 달리기에 적어봅니다
저도 잘은 모릅니다만, 덧글이 안 달리기에 적어봅니다.
1KB씩 잘라 송신한다는 말이 랜카드에서 나가는 패킷의 크기를 의미하는 것이라면, 한 번에 write()하는 데이터의 단위크기 그대로 패킷으로 만들어진다는 보장은 없습니다. write()는 커널의 소켓 송신버퍼에 데이터를 복사해넣는 일만 하고 빠져나올 뿐, 송신버퍼의 데이터를 어떤 크기로 패킷화 할 것인지는 커널 내부에서 알아서 합니다 (보통은 TCP 드라이버가 처리하되, LSO/TSO/GSO 같은 기능이 켜져있으면 랜카드 하드웨어 쪽으로 떠넘긴다는 정도로 압니다).
다만 write() 크기와 패킷크기가 전혀 무관하게 따로 노는 것은 아니며, 경험상, TCP_NODELAY 옵션을 켠 상태를 기준으로, 송신버퍼에 데이터가 쌓이는 속도가 패킷전송 속도보다 느리면 write() 크기가 패킷 페이로드 크기로 이어질 확률이 높아지고, 버퍼에 쌓이는 속도가 더 빠르면 패킷 크기가 달라지는 식인 것 같습니다. 눈으로 확인하려면 tcpdump나 wireshark같은 도구로 패킷캡처를 해보면 됩니다.
read/write 함수에 한계를 느꼈다고 하셔서 좀
read/write 함수에 한계를 느꼈다고 하셔서 좀 망설여집니다만,
readv/writev 함수를 이용하면 미리 나눈 다양한 크기의 버퍼들을 간편하게 사용할 수 있긴합니다.
...
뭐 kldp 게시판만 뒤져도 비슷한 답변이 제가 쓴 것만 한다스 나오겠지만 말이죠... -_-
> 수신버퍼에 1000번 수신해 1k씩 누적해서 1Mbyte를 받을수 있는가?
TCP는 스트림 프로토콜이기 때문에 보내는 쪽이 "1KB씩 1000번" 보냈다고 받는 쪽에서 그렇게 받는다는 보장 같은 건 전혀 되지 않습니다. (일단 보내는 쪽에서부터 "1KB씩 1000번" 보낼 수 있다는 보장이 안됩니다.) 유일하게 보장이 되는 건 (네트웍이 끊기지 않는 한) 1MB의 데이터를 보냈으면, 계속 읽다 보면 언젠가는 그 1MB를 다 받을 수 있다는 것뿐입니다.
그래서 TCP에 관련된 모든 책을 보면 read/write를 할 때 "내가 1000바이트를 보내라고/읽으라고 했는데 실제로는 몇 바이트를 보냈나/읽었나?"를 확인하고 남는 바이트는 반복해서 read/write를 불러서 처리하는 코드가 있습니다. 이건 TCP의 기본적인 개념이기 때문에 확실히 이해하시고 넘어가야 합니다.
댓글 달기