epoll 의 ET 사용법에 대해서...

leolo의 이미지

epoll을 사용해서 데이터를 읽어 들여야 하는데. 어떻게 처리해야 할지 몰라서 문의드립니다.

단순히 EAGAIN 까지 돌면서 읽는 것이 아니라.

특정 데이터 사이즈(24) 만큼 읽고, 거기서 body len을 읽고, 다시 body len을 읽어 들이는 것입니다.
ET를 사용할 경우 [A부분] 에서 EAGAIN가 발생할 떄까지 돌면서 읽어야 한다고 하는데.
정확히 어떻게 해야하는지 잘 모르겠습니다.

예들 들어 상대편이 100byte의 데이터를 보냈는데,
그걸 읽었을 때, 40byte의 온전한 데이터(header와 body로 구성된)가 2개 연속, 나머지 20byte의 온전한 데이터(header와 body로 구성된)가 존재하고 수신된다고 가정했을 때,
EAGAIN이 60byte 수신 후 발생, 나머지 40byte에서 또 발생한 경우에 대한 처리 같은 것이 궁금합니다.

/* epoll 파일 fd 저장소 생성 */
epfd = epoll_create(MAXEPOLLSIZE);
if(epfd == -1) {

}

/* epoll 인스턴스에 listen socket 등록 */
setnonblocking (lsk); // listen non-blocking
ev.events = EPOLLIN | EPOLLET; // READ, ET
ev.data.fd = lsk;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, lsk, &ev) <0)
{
return -1;
} else {
while(1) {

nfds = epoll_wait(epfd, events, curfds, -1);
if (nfds == -1) {
break;
}

for(n = 0; n < nfds; ++n) {

/* listen socket 접속 */
if(events[n].data.fd == lsk)
{
ask = accept (lsk, (struct sockaddr *) &their_addr, &len);
if(ask <0) {
continue;
}

setnonblocking (ask);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = ask;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, ask, &ev) <0)
{
return -1;
}
curfds ++;
}
else {
여기서 어떻게 처리해야할지.. [A부분]

}

sunyzero의 이미지

EAGAIN이 나올 때까지 읽어야 하는 것은 넌블럭킹 모드이기 때문이고, 트리거와는 상관이 없습니다.

보통 엣지 트리거를 사용하는 이유는 읽기 이벤트를 감지하는 부분과 실제로 읽는 부분이 분리된 경우에 주로 사용합니다.
비동기 처리를 하는 구조로 만들 때 편리하기 때문이죠.
(만일 LT트리거를 사용하면 감지하는 부분보다 읽는 부분이 느리면 읽기 전까지 계속 이벤트가 발생되므로 오버헤드가 됩니다.)

아니면 소켓 버퍼에 쌓인 크기를 확인해서 특정 크기 이상인 경우만 이벤트를 발생시키고자 하는 구조에도 사용합니다.

그러나 원글에서 가정한 상황은 트리거와는 상관없이, chunk를 분리하는 작업입니다.
이는 [A부분]의 서브 코드에 헤더 크기 만큼을 읽고 그 다음에 바디를 읽도록 하면 됩니다.
그리고 완성된 chunk는 콜백으로 보내면 되지요.
만일 미완성된 헤더나 바디가 발생하면 세션별(혹은 fd별) 저장소에 저장해두었다가 복구하면 됩니다.

========================================
* The truth will set you free.

leolo의 이미지

제가 잘못하겠는게..
fd 별로 저장소에 넣어서 처리하는 경우에 대해서 어떻게 구현을 해야하는지
어렵습니다.

또한, 상대편이 헤더에 바디 사이즈를 잘못넣었을 경우 어떻게 처리해야 할지도 답답합니다.

첫번째 메시지의 끝에 헤더의 일부가 존재하고
이어진 두번째 메시지의 앞부분에 헤더의 일부가 존재할 경우,
이런 경우라면 생각해보면
모든 fd에 대해서 큐잉해서 다른 쓰레드가 뽑아서 처리해야 하는 건지..
이러면 client 접속이 많을 경우에 문제가 좀 될꺼 같아서..

실력이 있으면 삶이 편하다... 영차 영차...

댓글 달기

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