TCP소켓에서 select에서 질문있습니다.

hellowee의 이미지

음..클라이언트가 요청 들어오면 그값을 send를 하는데.
이때 send크기가 4k이상이면..나누어서 보내야하나요?
아니면..send를 하면 알아서 TCP에서 짤라서 가나요?
아니면 send크기가 너무 크면 오버플로우가 발생하는지 그게 궁금하네요.
그럼 좋은 하루보내세요

펑키의 이미지

그냥 보내셔도 상관이 없을것 같은데요, 보통 4K 보다는 1.5K인가 아마 이쯤에서 짤리는것 같습니다. 정확한 사이즈는 저도 잘 모르겠네요. 하여간 보내는 사이즈는 얼마를 보내셔도 상관은 없지만 단 조건이 보내는 루틴이 보내는 사이즈만큼 보내도록 만들어져야 한다는 것입니다.

예를 들면 send(fd, ptr, size, 0) 해도 size 만큼 한번에 전송은 되지 않을 것입니다. 따라서 send() 리턴 해주는 값을 보고 얼만큼 전송이 되었다고 보고 만약 원하는 size - 1k 정도 라면 나머지 1k를 다시 보내줄수 있도록 코딩 하시면 될겁니다. loop 을 돌려야 된다는 말이죠. UNP 보시면 아마 나와있을겁니다.

만약 보내고자 하는 사이즈가 크고 빈번한것이라면 말씀 하신것 처럼 짤라서 보내주시는것도 참 좋은 방법 같습니다. 그러면 받는 쪽에서 기존에 받다 못받았으면 거기 부터 다시 받을수도 있으니깐요. 물론 이건 또 구현해야 되는거지만요.

즐거운 하루 되세요.

hellowee의 이미지

그럼 바로 send를 안하고..
send에 값을 큐에 넣고..
select에서
if(큐가 있는가)
{
FD_SET(socket, &wfds);
}

이렇게 하면
FD_ISSET(socket, &wfds)
{
여기서 send를 호출하면 이상이 없나요?

}

mach의 이미지

Quote:
이때 send크기가 4k이상이면..나누어서 보내야하나요?

4K라는 숫자가 왜 나오는지 이해할 수 없네요. 보통 Ethernet은 MTU가 1.5KB입니다. 4K를 MTU로 가지는 피지컬장치는 디스크류 말고 네트웍카드도 있나 궁금하군요. 그리고, 나누어 보낼 필요는 없지요. TCP프로토콜 스택이 알아서 해줍니다. 물론 TCP 상위에서 프로토콜을 만들어 나누어 보내는 전략도 좋습니다.
Quote:
아니면..send를 하면 알아서 TCP에서 짤라서 가나요?

예. 알아서 잘라서 보내고 알아서 합쳐서 받습니다.
Quote:
아니면 send크기가 너무 크면 오버플로우가 발생하는지 그게 궁금하네요.
오버플로우는 가능합니다만 다른 전산관련에서 바라보는 오버플로우하고는 용어 및 개념에 차이가 있습니다. 단지 block된다고 하지요. block되는 이유는 보내고자하는 양보다 원격지로 가는데 걸리는 시간이 더 걸리면 발생합니다. 이 경우에는 연결에 대해 blocking vs. non-blocking모드를 고려해야하는데, default로는 blocking으로 동작합니다(그러나, 이 또한 명시적으로 세팅하는게 좋습니다).
blocking mode인 경우에는 send()라는 호출에서 멈추고(block되고) 보내고자 요청한 양을 모두 보낼때까지(반면 상대측에서 받아줘야지요? 원격지가 받아주면, 버퍼가 비워지고 나머지를 계속보낼수있습니다.) 리턴하지 않습니다. 단 시그널이 발생하면(이를테면 Ctrl+C를 누른다거나....) 블럭킹에서 빠져나오지요. 보내고자하는 메시지의 크기가 64KB(최대로 세팅한경우)가 넘지 않는다면, 운영체제내의 TCP프로토콜스택이 받아놓고 알아서 보내게됩니다. 참고로, 운영체제가 내부적으로 처리해주는 부분이 있어서 TCP는 원론적으로 볼때, 비동기적입니다. 비동기라 함은 상대편 커널까지가면 신뢰적으로 전송되었다고 보는 관점에서 그러합니다. 동기라함은 상대편 응용이 받아야 받은것으로 인지하는 경우지요. 즉, send()의 리턴이 상대가 recv()했을때 된다면 그렇게 부릅니다.

Non-blocking인 경우에는 send()에서 절대로 block되지않고, 보낸만큼 바이트숫자를 리턴해줍니다. 리턴값에 대해 상세히 보셔야하고(에러,성공등등), 이를 카운트하고 더하고 계산해서 해당위치부터 다시 보내면 되겠지요.

* 근데, select()하고의 관계가 있나요? 음 실렉트를 써서 보낼 버퍼가 비워져있는지 검사해보고 보내면 되겠네요. 주의점은 1바이트만 비워져도 실렉트에서는 쓰기가능으로 인식합니다. 따라서, 보통의 경우라면 writable을 검사하면 항상 이벤트가 발생하게됩니다. 보낼 데이터가 없어도 쓸 수 있다는 이벤트가 select()를 자꾸 통과하게 되겠지요. 그래서 이부분의 로직은 데이터를 다수전송할때만 한시적으로 사용하시는게 좋겠습니다.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

펑키의 이미지

네 맞습니다. 그런데 메시지 큐에 데이터를 넣고 빼고 하는것은 처리하고자 하는 데이터가 특이한 상활일 경우에만 하시는게 좋을듯 싶습니다. 저의 경우 은행 시스템을 만들때 비즈니스 로직을 처리하는 서버가 받아 가게 하기 위해서 중간에 미들웨어 쪽에서 큐에 넣고 그 녀석이 가져 가게 하는 편입니다. 그런것이 아니라 그냥 클라이언트와 바로 상대하고 외부(내부)의 또 다른 서버가 존재하지 않고 특별한 작업을 하지 않는 서버라면 메시지 큐를 사용하지 않는게 더 편하실수 있을겁니다.

혹은 제가 잘못 알았을수도 있을겁니다. 말씀하신 큐라는게 그냥 버퍼를 말씀 하신것일수도요. 만약 그러하시다면 버퍼에 어떤것이 있을때 보내는 것 보다는 보내는 싯점을 로직에 넣으시는게 좋을듯 싶습니다. 즉, 버퍼에 어떠한것이 있을때라고만 하면 버퍼에 한개만 들어가고 다음에 주루륵 들어와야 하는데 이럴때 중간에 미리 보내버리기에는 좀 그렇죠.?

그래서 말씀 하신 내용중에 보면 보내는 상황에서 SELECT를 사용하실거면 먼저 SELECT 에서 쓰기 가능한 상황인지 알아 내십니다. 그런 다음에 쓰기 가능한 상황 이라면 그때 SEND를 하시는게 어떠실런지요.? 말씀 하신 내용이 틀리지는 않습니다. SEND할때 SELECT를 이용하실거면 SEND가 SELECT 이후에 쓰기 가능한지 검사하는 루틴에 넣어 두시면 좋을듯 싶습니다.

댓글 달기

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