전송 데이터가 다양한 데이터 타입일 경우, receive() 함수에서 수신 데이터를 처리하는 방법

standalon의 이미지

오래간만에 코딩하려니까 간단하지 않네요. ^^

C++로 소켓 프로그램을 작성중인데, 전송 데이터의 타입이 다양합니다. (ex. 기본 자료형, 구조체, 클래스, etc)
기존에 작성했던 프로그램에서는 같은 데이터 타입에 길이만 달라서 그 길이에 따라서 처리 프로세스를 구분해주곤 했는데, (예를 들면, 전송 데이터가 항상 byte array래서, 첫번째 byte를 byte array의 길이로 정의함.)
이번에는 데이터 타입 자체가 달라서 receive() 함수에서 수신 데이터를 어떤 데이터 타입으로 받아서 처리해야 할지 고민이 됩니다.

이런 경우가 이전에도 분명히 있을텐데, 아무리 찾아봐도 못 찾겠네요.
아시는 분 조언 또는 관련글 URL 부탁드립니다.
감사합니다.

ktd2004의 이미지

일단은 packet을 구분할 수 있어야할 것 같네요.

STX + LEN + DATA... + CHECKSUM + ETX

그리고 실제 DATA는 protocol buffer 같은 걸 사용해서 serialization하면 어떨까요???

Yi Soo An@Google의 이미지

다양한 데이터 타입이 있는 경우 header에 타입 정보를 넣어주고 그 뒤에 데이터를 붙이는 경우가 많습니다. 대표적인게 d-bus인데 이러한 방식은 네트워크간 통신에도 별로 다를것 같진 않다고 생각되네요.

---------------
Happy Hacking!

Hodong Kim@Google의 이미지

nimf 는 C 로 만들었는데,

https://gitlab.com/nimf-i18n/nimf/blob/master/libnimf/nimf-message.c
https://gitlab.com/nimf-i18n/nimf/blob/master/libnimf/nimf-message-private.h

nimf_send_message(), nimf_recv_message() 함수와 nimf-message-private.h 를 참고하시기 바랍니다.

헤더를 먼저 보내고, 다음에 데이터를 보냅니다. 현재 코드를 보니 헤더와 데이터를 한방에 보내는 것 같기도 합니다.

그래서 받는 측에서는 헤더를 먼저 받아서, 다음에 받을 데이터 타입과 길이를 미리 알고 있습니다.
그 다음 데이터를 받아서, 데이터 타입에 맞게 처리를 하고 있습니다.
https://developer.gnome.org/glib/stable/glib-GVariant.html 라는 직렬화 함수가 있긴 하지만, nimf 의 경우에는 그걸 사용하면 코드가 오히려 더 복잡해지고 코딩/디코딩에 시간이 좀 더 걸리기 때문에 그걸 사용하지 않았습니다.

통신이기 때문에 C++ 도 별반 다르지 않을 것이라 생각합니다.
제가 C++ 언어를 모릅니다. 만약 C++ 언어 자체에서 직렬화를 지원하면 그걸 사용하면 될 것 같고,
만약 없다면 위 nimf 의 예처럼, 헤더 보내고, 데이터 보내고,
받는 측에서는 타입과 길이를 먼저 파악하고, 데이터 들어오면 적절하게 처리하면 될 것 같습니다.
클래스를 보내는 방법은,
클래스에 필드가 있으니까, 클래스 이름(또는 id 또는 타입), 필드 데이터를 패킷 데이터로 만들어서 보내고,
받는 측에서 클래스 이름(또는 id 또는 타입)에 상응하는 클래스를 생성하고, 필드 데이터를 할당하면 될 것 같습니다.

라스코니의 이미지

현재 LV(Length,Value)로 해 오셨다는 말씀이네요.
TLV(Type,Length,Value)를 사용하시면 될 것 같습니다.

standalon의 이미지

님들, 좋은 답변 감사합니다.

댓글 달기

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