2009-12-07 3 views
0

UDP 소켓을 통해 구조체를 보내려고합니다.C에서 char []을 struct에 복사하는 방법

struct packet { int seqnum; char 데이터 [BUFFERSIZE]; };

그래서 발신자에 나는 그래서 내가 바라고 있어요

bytes = sizeof(packet); 
char sending[bytes]; 
bzero(sending, bytes); 
memcpy((void *) sending, (void *) &packet, sizeof(bytes)); 
bytes = sendto(sockfd, sending, sizeof(sending), 0, 
    (struct sockaddr *) &client, clientSize); 

이 그 숯불 []에 복사 내 구조체. 수신기

I은 ​​를 memcpy ((무효 *) currentpkt (무효 *) RECV 바이트)와 수신기

int bytes; 
bytes = sizeof(struct Packet); 
char recv[bytes]; 
bytes = recvfrom(sockfd, recv, bytes, 0, 
    (struct sockaddr *) &client, &clientSize); 
memcpy((void *) currentpkt, (void *) recv, bytes); 

그러나있다;

error: cannot convert to a pointer type

내가 잘못 뭐하는 거지 : 오류가 발생합니다? UDP 소켓을 통해 구조체를 보내는 더 좋은 방법이 있습니까?

***** UPDATE ***** 답변 모두에 대한

감사합니다. 결국 나는 '&'을 놓쳤지만 이제는 내 코드가 이렇게 보입니다.

보낸 사람 :

void udt_send(struct Packet packet) { 
    int bytes; 
    bytes = sendto(sockfd, (char *) &packet, sizeof(packet), 0, 
      (struct sockaddr *) &client, clientSize); 
} 

수신기 : 우리는 단지 문자로 캐스팅 바이트를 보내 수있는 그것의 좋은 것을 C에서

bytes = recvfrom(sockfd, (char *) &currentpkt, bytes, 0, 
     (struct sockaddr *) &client, &clientSize); 

.

+0

'currentpkt'란 무엇입니까? –

+0

struct packet currentpkt; // 전역 변수 –

+1

문제 # 1 : _ 전역 변수를 사용할 필요가 없을 때 전역 변수를 사용하지 마십시오 ._ –

답변

3

currentpkt은 구조형입니다. 이 작업을 수행하려면 구조체에 대한 포인터를 가져와야합니다.

memcpy(&currentpkt, recv, bytes); 

두 번째 질문에 대해서는 다른 문제가 있습니다. sizeof(struct Packet)보다 패킷에서 더 많은 바이트를 수신하면 어떻게 될까요? 지금 작성되었으므로 구조체가 오버런됩니다.

클라이언트 및 서버 응용 프로그램이 다른 컴파일러 또는 설정을 사용하여 컴파일되거나 다른 엔디안이 지원되는 플랫폼에서는 어떻게됩니까? 이 경우 구조체는 두 플랫폼에서 서로 다른 크기 일 수 있으며 메모리에 다르게 배치 될 수 있습니다.

+0

아아 ... 고마워, 이걸 =) –

+1

@ 베르니 : 제임스의 다른 점을 언급했는지 확인하십시오. 오버런을 위해서'memcpy'의 3 번째 인자를 더 잘 사용하십시오; 너무 많은 데이터와 너무 적은 데이터를 모두 처리해야합니다. 엔디안에 대해서는 'ntoh *'및 'hton *'함수 (예 : ntohl)를 살펴보십시오. 전역 변수는 함수 매개 변수로 변환되거나 적절한 구조체의 필드로 추가 될 수 있습니다. – outis

1

그래서 나는 currentpktstruct Packet이고 실제로는 &currentpkt이라고 말하고자합니다.

에는 이미 void * 매개 변수가 있으므로 (void *) 캐스트가 필요하지 않을 수도 있습니다.

+0

팁 주셔서 감사합니다. 그 무효 *를 제거합니다. –

0

memcpy((void *) currentpkt, (void *) recv, bytes);

귀하의 오류 메시지가 주조 문제가 있음을 나타냅니다. char[]이므로 recv은 괜찮습니다 ((*)로 변환해도 문제 없음). 문제는 currentpkt이 포인터 유형이어서는 안됩니다.

코드 조각에 선언되지 않았으므로 그 코드가 무엇인지 알 수는 없지만 시작하겠습니다.

0

전체 구조체에서 memcpy를 수행하는 것은 정말 위험합니다 .-). 우선 모든 데이터는 아키텍처에 따라 다르게 정렬 될 수 있습니다. 다른 측면에서 아키텍처가 다른 경우에는 어떻게해야합니까? 또한 __packed와 같은 키워드를 사용하면 다른 컴파일러간에 이식 할 수 없습니다.

PHP 팩/압축 풀기와 같은 API를 사용하는 것이 가장 좋습니다. 이렇게하면 __packed와 같은 컴파일러 관련 키워드를 사용하지 않고도 코드를 이식 할 수 있습니다.

나는 인터넷에서 C를위한 꾸러미/포장을 발견하지 못했고 그래서 나는 내 자신을 썼다.

이진 데이터에서 두 단어를 풀고 예를 들어

:

pbuf_unpack(p_entry, "bbbbbbbbww", 
     &atrb_mbr.def_boot_par, &atrb_mbr.head_start, &atrb_mbr.sec_start, 
     &atrb_mbr.cyl_start, &atrb_mbr.type, &atrb_mbr.head_end, 
     &atrb_mbr.sec_end, &atrb_mbr.cyl_end, &atrb_mbr.start_sec_pbr, 
     &atrb_mbr.sec_per_par); 

포장 매우 간단합니다 :

p_bts is binary data 
    "ww" describes the data structure 
    hdr and ver is where to put the datause an API like the PHP pack/unpack. 

또 다른 더 광범위한 예

pbuf_unpack(p_bts, "ww", &hdr, &ver); 

pbuf_pack(boot_buf, "sdsdhbhbhhbhhhwwbbbwsdsd", sizeof(fat_jmp_boot_t), 
     boot.jmp, sizeof(fat_oem_nm_t), boot.oem_nm, boot.n_bps, boot.n_spc, 
     boot.n_rs, boot.n_fs, boot.n_rde, boot.n_ts16, boot.media_des, 
     boot.n_fatsz16, boot.n_spt, boot.n_hds, boot.n_hs, boot.n_ts32, 
     boot.drv_no, boot.rsrvd1, boot.boot_sig, boot.vol_id, 
     sizeof(fat_vol_lbl_t), boot.lbl, sizeof(fat_vol_type_t), boot.type); 

이식성있는 코드를 만들뿐만 아니라 멋지기도합니다.)

관련 문제