receive를 받은 데이터를 파싱해서 구조체에 넣기

cjy1126의 이미지

찾아보니까 구조체 데이터를 send하는 법은

캐릭터 포인터 char * ptr에 PERSON형 구조체 per을 강제 캐스팅해서, 

ptr = ( char * ) & per;  ptr을 보내면 됩니다.

이렇게 나오는데, char형으로 receive한 데이터를 어떻게 구조체에 넣어야할까요?

	char num[5]; //index
	char ip[16]; //ip
	char sysdescr[128]; //host system 설명
	char sysupdate[30]; //system up time
	char type; //장치 타입
	char snmp_attach; //smnp 지원여부

구조체 멤버는 위에것들인데, 보내는 분이 #로 파싱하자고 하시네요.

sprintf(buf, "%s#%s#%s#%s#%c#%c", num, ip, sysdescr, sysupdate, type, snmp_attach);

이런식으로해서 보낸다는건데, ip랑 char 타입이야 크기가 정해져 있어서 하겠는데, 다른건 길이가 가변적이라서... 어떻게해야할지 모르겠습니다.

도움 부탁드립니다. :)

낙엽의 이미지

fix된 data라면 사이즈대로만 자르면 되겠지만, 가변이기 때문에 #이라는 구분자를 두었겠죠. 그냥 #으로 자르세요.

cjy1126의 이미지

그러니까 어떤식으로 '#'를 구분해야 하는지요? -_-;

한글자씩 읽어서 '#'까지 해야하나요?

그럼

while(c[i] != NULL)
{
   if(c == '#')
      count++;

   switch(count)
   {
      case 0: 구조체.첫멤버 = c;
            break;
      case 1: 구조체.두번째멤버 = c;
            break;
   }
   i++;
}

이런식으로 해야하나요?

지금 테스트가 끝나면 구조체 멤버가 15개정도될것 같은데... 다른방법은 없나요?

sylphong의 이미지

strtok로 짜르시면됩니다..
하지만 원본을 변경하니 주의해서 써야될겁니다...
좀더발전된 strsep가 있습니다만..ANSI표준함수가 아니죠..

alsong의 이미지

   char num[5]; //index 
   char ip[16]; //ip 
   int sysdescrlen; (or offset postion) <----
   char sysdescr[128]; //host system 설명 
   char sysupdate[30]; //system up time 
   char type; //장치 타입 
   char snmp_attach; //smnp 지원여부 

꼭 이런 형식으로 보내야 된다면.... 윗분말씀되로 하시면 되겠군요.
토큰으로 스트링 파싱 대신에 sysdescr의 길이정보를 넣거나 offset정보를 넣어서 처리하는 방법이 있습니다. 참고하시길

그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.

moonzoo의 이미지

Quote:

캐릭터 포인터 char * ptr에 PERSON형 구조체 per을 강제 캐스팅해서,

ptr = ( char * ) & per; ptr을 보내면 됩니다.

이렇게 나오는데, char형으로 receive한 데이터를 어떻게 구조체에 넣어야할까요?

보내실때 char 형으로 캐스팅 해서 보내셨다면 받을때도 마찬가지 입니다.

예를 들어 받는 버퍼를

char recv_buff[MAX_BUFF_SIZE];
...
receive한 data를 위의 recv_buff에 넣은후.
...

2가지 방법이 있는데

1. PERSON per;
    memcpy(&per , recv_buff, sizeof(per));

2. PERSON * pper;
    pper = (PERSON * )recv_buff;


이렇게 하시면 버퍼의 값을 구조체로 바로 사용가능합니다.
hekimian의 이미지

moonzoo님 말씀대로 정해진 구조체로 캐스팅 하시거나... memcpy 하시면 됩니다.

그리고 정해진 구조체가 있고 구조체로 보낸다고 하면 보내는 쪽에서 '#'으로 구분해서 보낼 필요는 없을 듯 합니다.
물론, 구조체의 각 멤버 변수의 size보다 큰 값이 들어가면 안되겠죠 ~! ^__^

♤♤
You can do it ~!

나를 죽이지 않는 모든 것은 나를 강하게 할 뿐이다.

cjy1126의 이미지

구조체 데이터 사이즈가 같나요?

둘이 사이즈가 같게 설정해줘야 한다면, 어떻게 하나요?

hekimian의 이미지

보내는 쪽과 받는쪽에 같은 구조체가 있어야 합니다.

같은 구조체란..
구조체 멤버 변수의 type과 size가 같아야 한다는 말입니다.
아실테지만.... 이름은 틀려도 상관 없구요.

♤♤
You Can do it ~!

나를 죽이지 않는 모든 것은 나를 강하게 할 뿐이다.

icebug의 이미지

이상한 부분이 있어서 이렇게 글을 올립니다.

send라는 함수는 주로 네트워크 데이터 전송시 사용하는것로 알고있는데

어떻게 구조체의 포인터를 전송해서 다른쪽에서 그것을 받아서 사용할 수 있는지
궁금합니다.

또한 각 구조체는 속도를 계산해서 패딩이라는 것을 사용하는데 같은 구조체라

하더라도 컴파일 옵션에 따라 패딩간격이 서로 틀린데 막 보내도 되는지요?

jemiro의 이미지

htons, htonl, ntohs, ntohl 를 사용해서,
Byte order 변환을 해주는것을 잊으면 고생합니다.

음 정수도 그냥 스트링으로 처리 해주는것이었군요.
그렇다면,
아래와 같이 buf를 만들어 보냈으면,

sprintf(buf,
	"%s#%s#%s#%s#%c#%c",
	num, ip, sysdescr, sysupdate, type, snmp_attach);

다음과 같이 간단하게 잘라낼수 있습니다.
strtok는 thread unsafe function 입니다.
사용하지 않는것이 좋습니다.

sscanf(buf,
       "%[^#]#%[^#]#%[^#]#%[^#]#%c#%c",
       num, ip, sysdescr, sysupdate, &type, &snmp_attach);
hekimian의 이미지

물론 구조체의 포인터(메모리 번지)를 보내는 것이 아니고 포인터가 가리키고 있는 곳의 값을 size만큼 보내는 것입니다.

그리고, 패딩에 관해선 당근 먼저 고려가 되어야 겠죠.
패딩에 관해선 아래와 같이 사용하시면 해결 될것입니다.

구조체 패딩에 관한 더 자세한 내용은 프로그래밍QnA란을 찾아보시면 있습니다.

Quote:
#pragma pack(1)

struct _AAA {
char ~~~
short ~~~
int ~~~~
};

icebug wrote:
이상한 부분이 있어서 이렇게 글을 올립니다.

send라는 함수는 주로 네트워크 데이터 전송시 사용하는것로 알고있는데

어떻게 구조체의 포인터를 전송해서 다른쪽에서 그것을 받아서 사용할 수 있는지
궁금합니다.

또한 각 구조체는 속도를 계산해서 패딩이라는 것을 사용하는데 같은 구조체라

하더라도 컴파일 옵션에 따라 패딩간격이 서로 틀린데 막 보내도 되는지요?

♤♤
You can do it ~!

나를 죽이지 않는 모든 것은 나를 강하게 할 뿐이다.

kyong의 이미지

icebug wrote:
이상한 부분이 있어서 이렇게 글을 올립니다.

send라는 함수는 주로 네트워크 데이터 전송시 사용하는것로 알고있는데

어떻게 구조체의 포인터를 전송해서 다른쪽에서 그것을 받아서 사용할 수 있는지
궁금합니다.

또한 각 구조체는 속도를 계산해서 패딩이라는 것을 사용하는데 같은 구조체라

하더라도 컴파일 옵션에 따라 패딩간격이 서로 틀린데 막 보내도 되는지요?

구조체의 포인터가 아니라 byte stream으로 전송되는 것입니다.

막 보내면 늘 동작하는 것이 아닙니다.
gcc에서는 __attribute__ ((packed)) 과 같은 유용한 옵션이 있습니다.

icebug의 이미지

Quote:
캐릭터 포인터 char * ptr에 PERSON형 구조체 per을 강제 캐스팅해서,

ptr = ( char * ) & per; ptr을 보내면 됩니다.

이것때문에 질문을 드린것입니다. ptr을 보낸다는것은 32bit CPU에서는 4바이트를 보내는것 아닙니까?

alsong의 이미지

아마도 send함수에 ptr을 넘긴다는 생각으로 말씀하신것 같군요.
물론 데이터 값으로 포인트를 보내면 안되겠죠.

그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.

jemiro의 이미지

icebug wrote:
Quote:
캐릭터 포인터 char * ptr에 PERSON형 구조체 per을 강제 캐스팅해서,

ptr = ( char * ) & per; ptr을 보내면 됩니다.

이것때문에 질문을 드린것입니다. ptr을 보낸다는것은 32bit CPU에서는 4바이트를 보내는것 아닙니까?

위와 같이 보낼때는 바이트 오더 꼭 챙겨야 합니다. :)

moonzoo의 이미지

Quote:

캐릭터 포인터 char * ptr에 PERSON형 구조체 per을 강제 캐스팅해서,

ptr = ( char * ) & per; ptr을 보내면 됩니다.

send에 ptr를 보낸다는 것은 포인터 ptr를 보낸다는 것이 아니라

ptr이 가리키는 번지의 내용을 len 만큼 읽어서 char 형으로 보내는

것입니다.

물론 문제가 한가지 있는데..

구조체의 멤버가 모두 char형이라야 한다는 것입니다.

int 등은 기기마다 size등이 다르기 때문에..

전송 구조체의 멤버를 모두 char 형으로 설계하시고..

atoi 등을 이용하셔서 나중에 형변환 하는것이 간편합니다.[/code]

펑키의 이미지

구조체라고 해도 평면적인 자료의 형태입니다. 단지 그 평면적인 자료의 형태를 특정한 크기 단위로 잘라 놓아서 정의 했다고 생각 해보시면 될겁니다. 따라서 통신상으로 구조체를 전송한다고 해도 실제로는 평면적인 데이터가 전송이 됩니다. 각 CPU별로 다른 타입의 크기를 나타 내는것은 패딩이 되지 않도록 구조체를 PACK해서 보내거나 받으시면 됩니다. 즉, 구조체 선언시에 하시면 될겁니다.

제대로 되었는지 확인 하실려면 보내기전에 선언된 구조체의 사이즈를 보시면 원하시는 사이즈인지 확인하실수 있습니다. 손쉽게 생각하실수 있는 부분은 스트림 형태의 데이터가 전송되었을때 원하는 사이즈 단위로 잘라서 사용하는것 보다는 구조체로 보내면 따로 파싱을 하지 않아도 편리합니다.

다만 말씀 드린 바이트 패딩만 주의 하시면 될겁니다.

송지석의 이미지

음 제 생각에 막 보내는 것은 문제가 있을 듯 싶습니다.

물론 보내는 쪽과 받는 쪽이 환경도 같고 endian도 동일하면 됩니다.

보통 통신 프로토콜에서는 구조체와 비슷하게 패킷구조를 스펙에서 정해주죠. 그럴 때,

만약에 바이트 단위로 구조체가 되어있다 하면 구조체 패딩 바이트 단위로 해서 채워넣을려면

윈도의 경우(VC) #pragma pack(1) 인가를 사용하면 될 것이고요

gcc에서는 구조체에 _attribute_(packed) 이었나를 사용하면 될 겁니다. (이건 기억이 잘 안나네요. 틀릴 수도 있습니다.) 예전에 여기 어딘가에 제가 조사해서 썼던 글이 있는데.. 음..

이렇게 하면 구조체가 한바이트 단위로 꽉꽉 눌러서 되고요.

그리고 하나 더, 보내는 쪽과 받는 쪽의 플랫폼이 달라서 endian이 다를 경우,

long(int)형과 short형의 데이터는 htonl htons 등을 사용해서 네트웍 오더로 바꿔주고 보내세요.

받는 쪽에서는 ntohl ntons를 사용해서 자기에게 맞는 오더로 바꿔주면 됩니다.

ps. 앗 다 쓰고 나서 보니까 다른 분이 이미 답변을 하신 거였네요.
답변이 많아서 두페이지에 걸쳐 있는 것을 모르고 1페이지의 마지막 글에 답변을 달았네요.

댓글 달기

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