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 구조체의 내용을 보내고 싶은데 어떻게 방법이 없을까요????
죄송해요 코드가 좀 복잡해 보이네요
클라이언트 쪽에서 별도의 수신 버퍼를 사용하지 않고
클라이언트 쪽에서 별도의 수신 버퍼를 사용하지 않고 msg를 재사용하는 이유가 있나요? 문제가 발생했을 때 recv()의 return value는 제대로 확인해 보셨나요? 그리고 같은 구조체를 사용했다고 하더라도, 해당 구조체가 네트워크를 통해서 전송될 것을 가정하고 만들어진 게 아니라면 서버와 클라이언트의 OS나 환경에 따라서 sizeof(struct)가 달라질 수 있습니다.
받을때, 보낼때의 return value를
받을때, 보낼때의 return value를 확인해보았을때는 write시 전송에 성공하는것으로 나오지만,
read 시 받는것에 실패하는것으로 -1 값이 나오더군요.
클라이언트의 환경은 서버와 같습니다. 로컬에서 하는중입니다.
struct hostent 를 확인해보세요,
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나
그게 아무래도 host내용 마다 addrlist나 aliases등이 동적으로 크기가 변하다보니, 그거에 맞춰서 통신 하기가 힘들어서...
주로는 h_name,addrlist,aliases 가 필요해서 구조체 전체내용을 보내면 되지 않을까 했었어요...
혹시나 다른방법이 있을까요?
댓글 달기