[질문] 리눅스에서 send()의 전송 가능한 패킷의 최대 크기

skjean의 이미지

안녕하세요..

급질 부탁드립니다.

socket API에서 send(), sendto()등을 보면
패킷 전송시 메시지의 크기를 인자로 주어야 합니다.
인자의 형식은 size_t len 으로 주어집니다.

이 길이가 얼마까지 가능한지요?
man page를 보면 다음과 같이 기술되어 있습니다.
구체적인 수치는 언급하지 않고 있어요..
도움 부탁드립니다.

메시지의  길이는   len.   으로  주어진다.  메시지가  너무  길어서  기초적인 
프로토콜을 사용해 자동으로 넘어갈 수 없다면, 에러 EMSGSIZE 가 반환되고,
메시지는 전해지지 않는다. 
불량청년의 이미지

TCP/IP에서 한번에 최대로 전송할 수 있는 패킷 싸이즈는 64k입니다.

IP구조체의 전체패킷크기를 저장하는 필드가 16Bit로 되어 있으니까요.

기타 상대측 윈도우 싸이즈의 크기도 영향을 줄겁니다. 수고하세요~!

H/W가 컴퓨터의 심장이라면 S/W는 컴퓨터의 영혼이다!

skjean의 이미지

넵.. 감사합니다.

그렇다면 send()에서의 전송 메시지 크기도
64K에 제한된다는 의미인지요???

구체적인 수치 언급이 없으니...실제 프로그램을
짜서 메시지 크기를 달리하여 전송해 보면서
return value를 확인해야 하는가요?

seed의 이미지

MTU값에 의해서 한번에 보내질수있는크기가 달라집니다.
이더넷의 경우는 MTU가 1500바이트라서...
IP헤더를 포함해서 1500바이트까지 보낼수있습니다.
MTU값은 하드웨어에 따라서 달라집니다.
그러므로 send()에서 길이 필드에 들어갈수있는 최대값은
옵션이 하나도 없다고 가정할때 1460(IP헤더,TCP헤더제외)이 됩니다.
제가알기로는 이렇습니다...틀린부분있으면 지적해주세요 ^^

skjean의 이미지

답변 감사드립니다.

MTU 문제는 Protocol 계층에서 알아서 잘라서
보내주지 않나요?
즉, send()일때의 사이즈가 크면 .. IP(??)에서
MTU에 맞게 잘라서 보내주는 것 같은데요....

음...
send() API의 length의 최대 크기에 대한 제한 값은
알기가 상당히 힘들군요...

좀 더 도와주시기를 바랍니다.
감사합니다.

pynoos의 이미지

send api의 최대 크기는 사실상 의미 없습니다.

send가 아무리 많은 양을 한꺼번에 전송한다고 할지라도, 그걸 이용해서 전송하면 그다지 좋지 않습니다.

정확히 send 함수의 최대 값인지 MTU를 알고자하는 것인지 알 수는 없지만, 만약 전자의 경우에 한 해서 말씀드립니다.

send가 block socket에 대해서 작용하는 것이라면, send buffer안에 빈공간이 있을 때마다 조금씩 보내어 다 보낼 때까지 멈춰있겠지만, non-block에서는 바로 내려옵니다. send buffer에 넣은 양만큼만 return하겠죠.

어쩌다가 그 값이 꼭필요한 건지 가능하면 설계를 바꾸시는 것이 좋겠습니다.

skjean의 이미지

네.. advice 감사드립니다. ^^;;

직접 메시지 크기를 변화시켜가면서
전송해 보았습니다.
send()의 에러없는 리턴이 목적지까지의 도착에 대한
확인을 해 주지는 않지만.. 여하튼 send() 자체의
성공은 메시지 크기가 65507바이트까지이군요..
그 이상은 -1을 리턴합니다.

문헌은 아직 발견하지 못했지만.. 실험만으로 따지면..
아마도 65500 바이트 근처의 크기가 API에서
전송 가능한 최대 크기일걸로 추측됩니다.

감사합니다.

Testors의 이미지

skjean wrote:
직접 메시지 크기를 변화시켜가면서
전송해 보았습니다.
send()의 에러없는 리턴이 목적지까지의 도착에 대한
확인을 해 주지는 않지만.. 여하튼 send() 자체의
성공은 메시지 크기가 65507바이트까지이군요..
그 이상은 -1을 리턴합니다.

문헌은 아직 발견하지 못했지만.. 실험만으로 따지면..
아마도 65500 바이트 근처의 크기가 API에서
전송 가능한 최대 크기일걸로 추측됩니다.

setsockopt() 에 SO_SNDBUF 옵션으로 소켓버퍼 크기를 바꿔서 테스트해보시면 다른 결과가 나올 것입니다.

쿨링팬의 이미지

KLDP Wiki 'BeeJ's Guide to Network Programming' 에서

Quote:
send()는 결과값으로 보내진 모든 바이트 수를 돌려주는데 이것은 보내라고 한 숫자보다 작을 수도 있다. 가끔은 보내고자 하는 데이터의 크기가 미처 감당하지 못할 만한 숫자인 경우도 있으며 이 경우 send()는 자기가 감당할 수 있는 숫자만큼만 보내고 나머지는 잘라 버린후 당신이 그 나머지를 다시 보내 줄 것으로 기대하는 것이다. 만약에 보내라고 한 데이터의 크기보다 작은 숫자가 결과값으로 돌아 왔다면 그 나머지 데이터를 보내는 것은 전적으로 당신의 책임인 것이다.

관련 URL
http://wiki.kldp.org/wiki.php/BeeJNetworkProgramming#s-4.6

짱이의 이미지

IP패킷의 최대크기는 65535이므로 TCP헤더 20 IP헤더 20을 제외하면 TCP계층이 한번에 전송할 수 있는 메시지의 최대크기는 65495이다.
그러나 실제로는 다음과 같은 이유로 메시지의 크기를 수백~1460으로 제한하여 전송한다.
TCP가 한번에 전송하는 메시지의 크기를 MSS(Maximum Segment Size)라고 하며 초기에 상대뱡 TCP에게 알려주는데, TCP는 전송할 데이터가 이보다 클경우 데이터를 MSS사이즈로 세분화하며 전송한다...이하생략
책에 이렇게 나와있네요..

skjean의 이미지

많은 분들 답변 감사드립니다.

소켓 버퍼의 크기와는 확실히 연관이 있네요..
감사드리구여...

좋은 날 되시기를 바랍니다. ^^;;
담에 또 뵙기를 바랍니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.