문제

UDP 소켓 위로 구조물을 보내려고합니다.

구조물 패킷 {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);

그래서 나는 내 구조물을 char []에 복사하기를 바라고 있습니다.

내가 가지고있는 수신기에

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);

그러나 수신기에서 memcpy ((void *) currentpkt, (void *) recv, 바이트); 오류가 발생합니다.

오류 : 포인터 유형으로 변환 할 수 없습니다

내가 뭘 잘못하고 있죠? UDP 소켓 위로 내 구조물을 보내는 더 좋은 방법이 있습니까?

***** 업데이트 *****

모두 답변 해 주셔서 감사합니다. 결국 나는 '&'를 놓쳤지만 이제 내 코드는 다음과 같습니다.

보내는 사람:

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

수화기:

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

C에서는 우리가 그것을 숯으로 던져 바이트를 보낼 수 있다는 것이 좋습니다.

도움이 되었습니까?

해결책

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

memcpy(&currentpkt, recv, bytes);

두 번째 질문에는 다른 문제가 있습니다. 패킷에서 더 많은 바이트를 받으면 어떻게해야합니까? sizeof(struct Packet)? 지금 쓰여진 것처럼 구조물을 오버런합니다.

클라이언트 및 서버 애플리케이션이 다른 컴파일러 또는 설정을 사용하여 컴파일되는 경우 또는 다른 엔지니어가 다른 플랫폼에서 어떻게됩니까? 이 경우 구조물은 두 플랫폼에서 크기가 다를 수 있으며 메모리에 다르게 배치 될 수 있습니다.

다른 팁

그래서 나는 그렇게 생각하고 있습니다 currentpkt a struct Packet, 그리고 당신은 정말로 말하려고했습니다 &currentpkt.

나는 또한 그것을 주목할 수도 있습니다 memcpy() 이미 가지고 있습니다 void * 매개 변수 (void *) 캐스트는 필요하지 않습니다.

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

오류 메시지는 캐스트 문제를 나타냅니다. recv a이기 때문에 괜찮습니다 char[] ((void*)로 변환하는 데 문제가 없습니다). 문제는 그게되어야합니다 currentpkt 포인터 유형이되어서는 안됩니다.

그것은 당신의 스 니펫에 선언되지 않았으므로 그것이 무엇인지 모르지만 거기서 시작할 것입니다.

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

내가 아는 바와 같이, 가장 좋은 것은 PHP 팩/포장과 같은 API를 사용하는 것입니다. 이로 인해 __packed와 같은 컴파일러 특정 Ugly 키워드를 사용하지 않고 코드를 진정으로 휴대 할 수 있습니다.

나는 그물에서 C에 대한 팩/포장을 찾지 못했기 때문에 내 자신을 썼습니다.

예를 들어 이진 데이터에서 두 단어를 포장하지 않으려면 다음과 같습니다.

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

어디에

   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_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);

포장은 매우 쉽습니다.

   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);

휴대용 코드를 생성 할뿐만 아니라 아름답습니다.)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top