ewouldblock (eagain) 에러 발생 원인이 뭘까요

standby의 이미지

소켓 프로그램에서 ewouldblock (혹은 eagain) 에러가 나는 이유는 무엇일까요

회사에서 이것때문에 골치좀 썩고 있네요 예민한 업무가 돌아가는 시스템이라;;;

소켓은 non-block으로 읽어들일게 없을 경우 발생한다고 알고 있는데...

막상 이런 에러를 접하게 되니 원인 파악이 힘드네요

무한 루프를 도는 건 아니구 select()함수를 써서 읽을게 존재할때만 읽거든요.

지금 개발자들의 추측은 네트워크 상태가 그다지 좋지 않아서 헤더부분만 도착하고 아직 뒷부분이 완전히 도착하지

않아서 발생한게 아닐까 추측하고 있습니다만;;;

어떻게 생각하시는지요.

소스중 실제 read하는 부분만 올려봅니다

/*
* TCP Read by String Size
*/
int SocketRead(int SockFd, char *rBuff, int rlen)
{
int nleft, nread, ret;

nread = 0;
nleft = rlen;
memset(rBuff, 0x20, nleft);

while(nleft > 0)
{
ret = read(SockFd, rBuff+nread, nleft);
if (ret < 0)
return ret;
else if (ret == 0)
{
#ifdef _LOGGING_MODE
MsgWrite("read : %s\n", strerror(errno));
#endif
break;
}
nleft -= ret;
nread += ret;
} /* end of whlie */

#ifdef _LOGGING_MODE
MsgWrite ("RECV : (%d) %s!\n", nread, SUBSTR(rBuff,1,nread));
#endif

return nread;
}

standby의 이미지

움;;

초코리의 이미지

중복 삭제..

초코리의 이미지

중복으로 올라갔습니다.
삭제...

초코리의 이미지

select read부분은
일단 패키이 도착하면 리턴이 되므로
read중간에 wouldblock이 발생할수 있습니다.
wouldblock이 발생하면
다시 select대기하셔야합니다.

쉽게 말해 100byte를 보냈는데 10byte만 도착해도
select는 리턴됩니다.

standby의 이미지

아래와 같이 while 루프가 돌면서 read를 계속 실행할텐데요
설령 100바이트 중 10바이트가 돌더라도 10바이트가 리턴되면서 ewouldblock에러를 발생시키는게 아니라... 나머지 90바이트를 읽으려고 하지 않나요?

소스도 올렸는데 잘리네요

while(nleft > 0)
{
ret = read(SockFd, rBuff+nread, nleft);
if (ret < 0)
return ret;
else if (ret == 0)
{
#ifdef _LOGGING_MODE
MsgWrite("read : %s\n", strerror(errno));
#endif
break;
}
nleft -= ret;
nread += ret;
}

초코리의 이미지

블러킹 모드라면 그곳에서 대기하는게 맞지만
논블러킹 모드여서 에러가 발생하는 것이 맞습니다.

좀 편하게 하려면
would_block일때
continue;에서 while 루프에서 돌면 됩니다만..
이러면 논블럭모드를 사용하는 의미가 없습니다.

standby의 이미지

의미가 없는건가요? (죄송합니다. 제가 좀 지식이 짧아서;;)
총 1000바이트가 오기로 했는데 읽었더니 100바이트만 와있다고 했을때 ewouldblock에러가 발생하는 것이 아니라
100바이트를 읽고 다시 루프를 돌면서 나머지도 읽는 프로그램인데 처음 한번 읽을 때 1000바이트가 아니면 에러를
발생한다는 것인지.. 그렇다면 개발자 말이 맞는건데 그러면 왜 while문을 처음부터준건지 잘 모르겠네요

초코리의 이미지

일단 1000바이트를 받을때
100바이트가 왔을때 리턴이 왔다면

read시에 100바이트를 읽을 것입니다.
while에서 다시 루프를 돌때
뭔가 읽을것이 있다면 정상적으로 얼마정도 읽겠지만
아직 데이터가 오지 않았다면
이시점에서 eagain 에러가 발생하는 것입니다.

^^:: 논블러킹에 관련된 자료를 좀더 찾아보셔야
좀더 이해하실수 있을것 같습니다..
Unix Network Programming 책 추천드립니다.

standby의 이미지

공부하겠습니다 ^^;;

댓글 달기

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