[완료] send() 시 -1 리턴문제

binalee의 이미지

안녕하세요. 궁금한게 있어서 질문 드립니다.

socket통신에서 send()를 할 때, -1 (EAGAIN)을 리턴 받을 경우가 있잖아요
주로 send buffer가 꽉 차서 더이상 쓸 수 없는 경우나 그외 다른 이유에 의해서 발생하는 것으로 알고 있는데요
궁금한 것은 -1을 리턴 받으면 send buffer에 전혀 1바이트도 쓰지 않고 그저 리턴하는 것인지
아니면(그럴리 없다고 생각되지만) 조금이라도 쓰고 리턴될 수 있는지 궁금합니다.
현재 저는 넌블럭 모드에서 -1을 리턴 받으면 sleep(1)을 하고 다시 전송하는데 어떨 때는 잘 전송되지만
어떨때는 잘못된 데이타가 전송되는 것 같아서요..

그럼 답변 부탁드립니다.

antaran의 이미지

안녕하세요.

manual보시면 쓴 byte 수만큼 리턴 합니다. -1은 못 쓴 상황입니다. 기존 return 값을 보고 partial I/O 처리는 해주신 건가요? 데이터가 잘 못 간다고 하시면 송 수신 부분(당연한 -_-;;)을 잘 확인해 보시기 바랍니다.

Necromancer의 이미지

errno 값을 확인해야 합니다.

에러코드중 EINTR 외에는 전부 에러입니다.
EINTR은 send() 함수 수행중에 시그널 받았을때 온거기 때문에 다시 돌리면 되고요.

Written By the Black Knight of Destruction

Written By the Black Knight of Destruction

binalee의 이미지

에러코드는 11 (EAGAIN)을 받아요 리턴 값이 -1일때
그러면 저는 약 2초간 sleep했다가 다시 그 메세지를 재전송 하거든요.(버퍼가 비워지길 기다리며)
물론 리턴 값이 -1이 아니고 실제 쓴 바이트라면 partial sending을 해주고요

그런데 -1을 받으면 소켓을 끊고 다시 재연결을 하는게 맞는것 같은데 그럴 상황은 아니거든요..
혹시 이게 문제가 될 수 있을까요?

*** 제 알고리즘 ***

   write_bytes = send(sock_fd, buf, SIZE_TO_SEND, MSG_DONTWAIT); //넌 블럭 모드로 전송
 
   if(write_bytes == SIZE_TO_SEND) // 성공
   { 
      //OK!! SEND NEXT MESSAGE
   }
   else  
   {
       if(write_bytes == -1) // 쓰기 실패 시 (errno는 100% -11임)
       {
          sleep(2);      // 2초간 sleep 후 그 메시지 다시 전송
           RE_SEND(sock_fd, buf, SIZE_TO_SEND); 
       }
       else  // 일정 부분만 쓰기 성공 시 (errno는 42)
       {
          buf += write_bytes;                  // buf의 포인터를 변환 후
           SIZE_TO_SEND -= write_bytes;        // 사이즈 조절하고  
           RE_SEND(sock_fd, buf, SIZE_TO_SEND); // 재전송
       }
   }

감사합니다

binalee의 이미지

-1을 받으면 절대 버퍼에 쓰지 않는군요. 답변 감사드립니다.
그래서 지금 열심히 select로 send buffer가 writable한지 체크하는 방법 알아보고 있습니다. (쉽지않지만 ㅠ.ㅠ)

그럼 좋은 하루 되시길 바랍니다.

감사합니다

superkkt의 이미지

우선 -1이 리턴되면 전송된, 정확히는 소켓의 send buffer에 추가된, 데이터는 없습니다. 그런데 소스에서처럼 무작정 sleep 하지 마시고 select를 사용해서 소켓이 writable이 될때까지 대기하도록 바꾸시는게 좋을것 같습니다.

======================
BLOG : http://superkkt.com

======================
BLOG : http://superkkt.com

댓글 달기

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