CAsyncSocket을 이용해 통신을 하려고 하는데 vector와 string 클래스를 바로 보낼수 있나요?

kknd345의 이미지

처음에 CSocket을 이용한 CArchive의 Serialize로 통신 구성을 했습니다.

그런데 이 경우 여러개의 소켓을 사용할 때 OnReceive가 무시되는 경우가 발생해서

CAsyncSocket을 이용해 통신을 하려고 하는데

CAsyncSocket은 recv를 할때 그냥 char나 byte 버퍼에다 데이터를 받아오는 방식입니다.

그렇다면

class bb
{
int a;
string b;
}

class aa
{
string name;
string id;
string tt;
vector info;
}
가 있을때

만약 제가 클래스 aa 를 통신으로 보내고 싶어
memcpy( buf, aa, sizeof(aa) );
이런식으로 버퍼에 내용을 채워서 통신으로 보낸후
유사하게 memcpy로 클래스에 바로 복사를 하여 구성하면 별 문제 없이 클래스가 보낸 상태 그대로
받은쪽 컴퓨터에서도 내용이 채워지나요?

아니면 간단한 다른 방법이 없나요?

그리고 string 클래스를 char 배열로 변환해서 안 보내도 문제 없나요?

klara의 이미지

네트워크로 보내는 것에 대해서는 잘 모르겠어서 보내고 받는 부분에서 문제가 있는지는 모르겠지만, memcpy를 이용해서 객체를 복사하는 부분은 문제가 있습니다.
std::string의 경우는 성능을 위해서 implicit sharing이란 것을 통해서 구현된 경우가 있습니다. 이경우 너무 빈번한 복사를 방지하기 위해서, 데이터를 별도의 공간에 격납하고, 데이터에는 포인터로 접근하도록 되어있습니다. 그리고 대입연산자나 복사 생성자를 이용한 복사에 대해서는 포인터만 복사하고 데이터는 복사하지 않고, 실제로 데이터의 복사가 필요한 경우에만 데이터를 복사하도록 되어있습니다. 따라서 단순히 memcpy를 하면 포인터의 주소만 복사될뿐 실제 데이터는 복사되지 않습니다. 그럼에도 불구하고, 이경우에는 대입연산자나 복사생성자가 호출되지 않았기 때문에 reference count는 변하지 않습니다.

std::string *s1 = new std::string("test");
std::string s2;
memcpy(&s2, s1, sizeof(*s1));
delete s1;
int size = s2.size();

std::string이 implicit sharing을 이용해서 구현되었을 경우, 위 코드는 마지막 라인에서 런타임 에러가 발생하게 됩니다. memcpy를 통해서는 reference count가 증가하지 않기 떄문에 delete s1에서 "test"에 대한 데이터가 삭제되버리고, s2내부에서 implicit sharing을 위한 포인터는 댕글링포인터가 되버립니다.

std::vector의 경우는 implicit sharing이 없지만, 클래스는 기본적으로 내부동작을 은폐하고 있기 때문에, 복사 생성자나 대입연산자를 이용하지 않은 복사에 대해서는 안전성을 장담할 수 없습니다.

더군다나 네트워크로 전송한다면, 메모리주소란 것은 아무런 의미가 없으므로, 포인터를 포함하고 있는 클래스라면 implicit sharing을 하던 안하던 memcpy만으로는 제대로된 데이터 전송이 불가능 하겠지요.

cppig1995의 이미지

당연히 문제가 생깁니다.
저게 문제가 없으면 세상에 serialize라는 개념은 없어도 되겠죠?

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

댓글 달기

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