IOCP 를 이용 직렬 통신 프로그램을 작성해 보신 분 계신가요?

체스맨의 이미지

리눅스 관련 내용은 아닙니다만...
주제가 맞지 않으면 삭제하셔도 관계 없습니다.

제가 원하는 답변은 다음 두가지 입니다.

1. IOCP 로 직렬 통신 프로그램을 작성할 수 있는가.
( 저는 하다가 실패했구요. )

2. 작성할 수 있다면 예제를 구할 수 있는가.
( 웹에서 찾을 수가 없었습니다. )

상황에 대한 부가 설명을 드리면,

리눅스와 윈도 등에서 모두 사용할 수 있는 비동기 직렬 통신 관련
함수를 작성하고 있습니다. 리눅스쪽은 RTS 를 이용해서 작성했고
잘 실행되는데요.

윈도에서는 Overlapped I/O 를 이용하는 경우는 예제도 많고,
잘 작동하는 것을 확인했습니다만, IOCP 를 이용하는 경우는
현재로는 미궁에 빠져있습니다. 현상은 GetQueuedCompletionStatus
가 두번째 호출될 때부터 입력이 없어도 대기상태에 있지
않는다는 것인데요.

MSDN 에는 분명히 GQCS 함수가 WaitCommEvent 를
처리할 수 있다고 되어있는데, 실제로는 그렇지 않은 것 같습니다.

혹시라도 개발을 해보신분이 계실까해서 질문을 올립니다.
데브피아나 코드그루는 이미 거쳐왔습니다.

익명 사용자의 이미지

잘은 모르지만... 시리얼 드라이버가 잘 연결되어있는게 아니라면 IOCP에 연결하는건 어려울수도 있을것 같습니다. 시리얼은 보통 폴링이라.....

체스맨의 이미지

MSDN 상으로는 되어야 정상입니다. 된다고 되어있으니까요.
소켓은 물론 파일 입출력까지 잘 처리하는 IOCP 가 직렬 통신은
안된다는 건, 제가 무언가 잘 못한 것이거나 (아마 이것 같은데
참고할 게 없으니 정말 답답하네요.) 만에 하나 IOCP 버그겠죠...

리눅스에서는 폴링 없이 async 하게 잘 되네요.
RTS 로 잘 되더군요. 그러니까 RTS 로 소켓 통신과 시리얼 통신을 함께
async 하게 진행하는 게 무리가 없었습니다.

Orion Project : http://orionids.org

체스맨의 이미지

성공 했습니다. :lol: 고로, MSDN 에 적혀있는대로 잘 되는 것이군요.

Orion Project : http://orionids.org

체스맨의 이미지

음... 참고가 되실까해서 적어봅니다.

오늘 혹시나해서 표준 입출력 핸들에 대해 IOCP 를 적용해봤는데요. 리눅스 RTS 와는 달리 윈도에서는 IOCP 로 표준 입력은 처리할 수 없네요. CreateIoCompletionPort 가 실패합니다.

다음은 제가 테스트한 코드입니다. ( 제 결론은 안된다인데, 잘 못 테스트됐을 수도 있겠습니다. )

#include <stdio.h>
#include <windows.h>

int
main( void )
{
    HANDLE stdin_handle, iocp, stdout_handle;

    stdin_handle = CreateFile( "CON",
        GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
        OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED, NULL );

    stdout_handle = CreateFile( "CON",
        GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
        OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED, NULL );

    iocp = CreateIoCompletionPort( stdin_handle, NULL, 0, 1 );

    if( iocp ) {
        CloseHandle( iocp );
        puts( "O.K." );
    }
    else {
        printf( "Error = %lu, stdin=%p, stdout=%p invalid_handle=%p\n",
            GetLastError(), stdin_handle, stdout_handle, INVALID_HANDLE_VALUE );
    }

    return 0;
}

Orion Project : http://orionids.org

익명 사용자의 이미지

좀 어뚱한 생각일 수 있는데요...
IOCP만으로 안되는 것뿐이 아닐까요?

우회로 같은 것을 이용한다면 어떨까요?

이를테면, 전화접속 연결을 지원하고,

이는 PPP/SLIP 같은 것으로 TCP/IP를 구현해주기 때문에

엄밀히 말하면 IOCP를 이용해서, 시리얼포트로 데이터를 보낼 수는 있죠...

리눅스단에도 같은 설정을 해주면,
시리얼 널 케이블을 통해서 그냥 TCP로 통신도 가능할 것 같은데...

그런데 이건 본래 취지하고 달라지나요?

체스맨의 이미지

아니요... 제 글이 약간 모호한 것 같은데요.

IOCP로 직렬 통신 구현하는 것은 성공리에 마쳤습니다.
어디 문서도 없어서, GQCS 를 한 번 더 호출해야 한다는 사실을 알지 못해 엄청 헤맸지요.

이번에는 stdin 에서 문자들을 읽어오는 테스트였는데요... 그러니까 예를 들어 X 윈도 프로그램에서 X 윈도 이벤트 루프가 작동하면서 표준 입출력에서도 입력을 얻고자 하는 경우 X 윈도가 작동하는 스레드를 scanf 등으로 블럭 시키면 안되니까 비동기적으로 읽어와야 하는 경우에, RTS 나 IOCP 스레드에서 겸사로 읽어오려는 생각이었습니다.

아직 안해봤지만 리눅스에서는 될 것 같고, 위 테스트 결과에 따르면 윈도에서는 별도 스레드를 만들어서 거기서 문자 입력을 처리해야 할 것 같은데요...

Orion Project : http://orionids.org

댓글 달기

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