소켓라이브러리 함수중에 recv()함수에 대해서

rockme의 이미지

소켓을 이용한 클라이언트/서버소스를 보니 의문점이 있어서 글을 올립니다.

클라이언트 쪽에서 send()로 4096바이트를 한번에 보내고 서버쪽에서는 recv()를 사용해서 1024바이트씩 루프를 돌면서 받는 부분이 있습니다.
왜 송신 할때는 4096을 한번에 보내면서 수신할 때는 1024바이트씩 나누워서 받는 것인지 궁금합니다.

송신 할 때 어플리케이션에서 큰 데이터를 보내면 tcp에서 mtu에 맞게 조정되어 보내게 되기 때문에 수신측에서는 이것을 감안해서 위와 같이 작게 나누어서 받는 것입니까? 아니면 제가 모르는 recv()함수의 특성이 있는 것입니까?

musiphil의 이미지

TCP의 "stream" 특성상 보내는 덩어리의 구분도 아무런 의미가 없고 받는 덩어리의 구분도 아무런 의미가 없을 뿐입니다. recv() 함수에 어떤 독자적인 특성이 있는 것은 아닙니다.

rockme의 이미지

예. 그럼 수신측에서는 커널의 버퍼가 꽉찰 수 도 있기 때문에 그럴경우 데이터가 잘려질 수 있으므로 작은 크기로 반복적으로 수신해야 될 지도 모르겠군요.

그저 저의 생각이었습니다.

The sun behind the clouds is still shining

choissi의 이미지

그래서, tcp/ip 통신과는 별개로. 사용자 응용프로그램에서도
나름의 프로토콜을 구성을 하지요

읽었을때 패킷이 완성 된다는 보장이 없으니.. size + 내용
이런식으로 구성을 해서, size만큼 받기 전까지 계속
recv를 해야겠지요..

울랄라~ 호기심 천국~!!
http://www.ezdoum.com

송지석의 이미지

커널의 버퍼라.. 일단 tcp 버퍼는 생각하시는 것보다 상당히 클겁니다.

수백K정도는 그냥 버퍼링되는 것으로 알고 있습니다만.

대신에 tcp에서 send하면 결국 이더넷이나 무선랜처럼 사용하시는 미디엄으로 내려보내서 보내질텐데요

mtu 말씀하신 것도 맞고요. send시에 4K를 보내더라도 미디엄의 특성상 패킷크기가 달라서 잘려서 내려갈 수 있습니다. (이더넷이 1500바이트였나 하는 것으로 기억합니다만... 틀릴 수도... 가끔 통신 속도 튜닝할 때 mtu값을 조정하는 것이 이 미디엄-아래 레이어-에 따라 최대 값을 조정해주는 것입니다)

tcp는 스트림이 손상없이 가는 것을 보장해주지 패킷 단위로 가는 것을 보장해 주지는 않기 때문에 4K의 데이터가 단번에 전송된다는 보장이 없습니다. (udp는 패킷 단위로 전송됩니다. 대신 패킷이 중간에 깨져서 잃어버릴 수 있습니다.)

recv에서 4096바이트를 기다릴수도 있고 그렇게 해도 별 문제 없이 동작할 겁니다. 대신에 4096바이트를 한꺼번에 받지는 않을 수 있습니다. 그래서 리턴되는 값을 읽어서 얼마를 받았는 지 보고 처리해야겠지요.

send에서 보낸 4096바이트를 한번에 전부 받는 것을 보장하시려면 recv에서 WAITALL 플래그를 옵션에 켜시고 하면 됩니다..

ping할 때 옵션중에 -s 가있습니다. 보낼 패킷 길이를 정하는 것인데요. -s 4096하시고 핑하시면 대부분 패킷이 잘려서 갔다고 나올 겁니다. 보통 1400~1500근처에서 잘립니다.
tcp도 아래 레이어는 ping할 때와 같은 미디어를 사용하니까 큰 단위로 보내면 아래 레이어에서 잘려서 가지요. 받는 쪽에서 recv를 콜하는 시점에 따라 tcp레이어가 보낸 모든 데이터를 받아서 합쳐 가지고 있을 수도 있고 아직 일부만 받아서 가지고 있을 수도 있습니다. 그 상황에 따라 전부 받을수도 있고 일부만 받을 수도 있는 겁니다.

musiphil의 이미지

rockme wrote:
예. 그럼 수신측에서는 커널의 버퍼가 꽉찰 수 도 있기 때문에 그럴경우 데이터가 잘려질 수 있으므로 작은 크기로 반복적으로 수신해야 될 지도 모르겠군요.

그저 저의 생각이었습니다.


그런 처리는 TCP에서 알아서 다 해 줍니다. (congestion control)
아주아주 특수한 경우가 아니면 일반 사용자 프로그램에서는 신경쓸 필요가 없습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.