Linux로 C언어 소켓 네트워크 프로그래밍중 구조체 전송에 대해

익명 사용자의 이미지

제목 그대로 Linux 환경에서 C언어로 소켓프로그래밍을 사용하는데
구조체, 이 경우엔 net.db 안에 있는 hostent를 보내려고 하는데 어찌 안될까요??

<서버> while(1) { str_len = read(clnt_sock,msg,BUF_SIZE); //puts(msg); if(!strcmp(msg,"q\n") || !strcmp(msg,"Q\n")) { puts("closing!"); close(clnt_sock); break; } msg[strlen(msg)-1] = '\0'; strcpy(msg2, msg); addr = inet_addr(msg2); // write(clnt_sock,msg,sizeof(msg)); if(addr == INADDR_NONE) { host = gethostbyname(msg); } else { check_adr.sin_addr.s_addr = inet_addr(msg); host = gethostbyaddr((char*)&check_adr.sin_addr,4,AF_INET); }

write(clnt_sock,(char*)host,sizeof(host));
}

<클라이언트> while(1) { printf("Type IP or Domain to look up(Q to end) >"); fgets(msg, sizeof(msg),stdin); write(sock,msg,BUF_SIZE); if(!strcmp(msg,"q\n") || !strcmp(msg,"Q\n")) break; str_len = read(sock,msg,sizeof(msg)-1); msg[str_len]='\0'; host = (struct hostent*)msg; printf("Host Name : %s\n", host->h_name); for(i=0; host->h_aliases[i];i++) printf("Host aliases :%d: %s\n",i+1, host->h_aliases[i]); printf("Host IP version : %s\n", (host->h_addrtype == AF_INET)?"IPv4":"IPv6"); printf("Host Length : %d\n", host->h_length);

while(*host->h_addr_list != NULL)
{
printf("%s\n", inet_ntoa(*(struct in_addr *)*host->h_addr_list));
host->h_addr_list++;
}

}

이런식으로 서버의 host를 char로 캐스팅 후에 클라이언트에서 다시 받아서
클라이언트에서 다시 구조체로 캐스팅 해줘서 출력할려고하는데, 클라이언트쪽에서 오류가 나더라구요...

전송자체는 된거같지만 데이터 내용이 잘 안가서 문제가 생긴거같은데

아 그리고 저 코드 전에는 바로
write(clnt_sock, host, sizeof(struct hostent));

read(sock, host, sizeof(struct hostent));
이렇게 보내봤었지만 여전히 오류가 나더라구요....

hostent 구조체의 내용을 보내고 싶은데 어떻게 방법이 없을까요????

글쓴이의 이미지

서버
while(1)
    {
        str_len = read(clnt_sock,msg,BUF_SIZE);
 
        //puts(msg);
        if(!strcmp(msg,"q\n") || !strcmp(msg,"Q\n"))
        {
            puts("closing!");
            close(clnt_sock);
            break;
        }
        msg[strlen(msg)-1] = '\0';
        strcpy(msg2, msg);
        addr = inet_addr(msg2);
       // write(clnt_sock,msg,sizeof(msg));
        if(addr == INADDR_NONE)
        {
            host = gethostbyname(msg);
        }
        else
        {
            check_adr.sin_addr.s_addr = inet_addr(msg);
            host = gethostbyaddr((char*)&check_adr.sin_addr,4,AF_INET);
        }
 
        write(clnt_sock,(char*)host,sizeof(host));
    }
 
 
 
 
클라이언트
 
while(1)
    {
        printf("Type IP or Domain to look up(Q to end) >");
        fgets(msg, sizeof(msg),stdin);
 
        write(sock,msg,BUF_SIZE);
 
        if(!strcmp(msg,"q\n") || !strcmp(msg,"Q\n"))
            break;
 
 
        str_len = read(sock,msg,sizeof(msg)-1);
        msg[str_len]='\0';
        host = (struct hostent*)msg;
        printf("Host Name : %s\n", host->h_name);
        for(i=0; host->h_aliases[i];i++)
            printf("Host aliases :%d: %s\n",i+1, host->h_aliases[i]);
        printf("Host IP version : %s\n", (host->h_addrtype == AF_INET)?"IPv4":"IPv6");
        printf("Host Length : %d\n", host->h_length);
 
        while(*host->h_addr_list != NULL)
        {
            printf("%s\n", inet_ntoa(*(struct in_addr *)*host->h_addr_list));
            host->h_addr_list++;
        }
 
 
 
    }
익명 사용자의 이미지

클라이언트 쪽에서 별도의 수신 버퍼를 사용하지 않고 msg를 재사용하는 이유가 있나요? 문제가 발생했을 때 recv()의 return value는 제대로 확인해 보셨나요? 그리고 같은 구조체를 사용했다고 하더라도, 해당 구조체가 네트워크를 통해서 전송될 것을 가정하고 만들어진 게 아니라면 서버와 클라이언트의 OS나 환경에 따라서 sizeof(struct)가 달라질 수 있습니다.

글쓴이의 이미지

받을때, 보낼때의 return value를 확인해보았을때는 write시 전송에 성공하는것으로 나오지만,
read 시 받는것에 실패하는것으로 -1 값이 나오더군요.
클라이언트의 환경은 서버와 같습니다. 로컬에서 하는중입니다.

익명 사용자의 이미지

struct hostent 를 확인해보세요,

https://www.gnu.org/software/libc/manual/html_node/Host-Names.html

대충보면, member로 char *h_name를 가지고있듯이 array아니라 char *이어서, write(clnt_sock,(char*)host, sizeof(host)); 로 보내지는 데이터는 h_name의 full data를 가지고 있지 않고 char *만을 포함해서 4byte-32bit(or 8byte-64bit)만을 포함하겠네요. 구지 struct hostent를 전부보내야하는 이유가 있나요?

글쓴이의 이미지

그게 아무래도 host내용 마다 addrlist나 aliases등이 동적으로 크기가 변하다보니, 그거에 맞춰서 통신 하기가 힘들어서...
주로는 h_name,addrlist,aliases 가 필요해서 구조체 전체내용을 보내면 되지 않을까 했었어요...
혹시나 다른방법이 있을까요?

댓글 달기

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