无法通过C中的UDP套接字接收完整整数数组

时间:2015-12-27 14:02:23

标签: c++ c arrays sockets

这是我的发件人端代码

void send_data(int port, int coords[4]){

    struct sockaddr_in si_me, si_other;
    int s, i, slen = sizeof(si_other), recv_len;
    char buf[BUFLEN];

    //create a UDP socket
    if((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
        err_print("socket");
    }

    //zero out the structure
    memset((char*)&si_me, 0, sizeof(si_me));

    si_me.sin_family = AF_INET;
    si_me.sin_port = htons(port);
    si_me.sin_addr.s_addr = htonl(INADDR_ANY);

    //bind socket to the port
    if(bind(s, (struct sockaddr *)&si_me, sizeof(si_me) ) == -1){
        err_print("bind");
    }
    int size = sizeof(coords);
    printf("Size: %d\n", size);
    //Keep listening for data
    while(1){
        printf("Waiting for Data\n");
        fflush(stdout);

        memset(buf, 0, BUFLEN);
        //try to receive some data, this is a blocking call
        if((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, &slen)) == -1){
            err_print("recvfrom()");
        }

        //print details of the client/peer and the data received
        printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
        printf("%s\n", buf);

        if(!strcmp(buf, "coords")) {

            printf("Sending Coordinates: \n");
           //now reply the client with the same data
            int siz = sendto(s, coords, sizeof(coords), 0, (struct sockaddr*) &si_other, slen); 
            if(siz == -1){
                err_print("sendto()");
            }
            printf("Siz: %d\n", siz);

            }

            break;
        }

    }

    close(s);
}

sendto返回的值是8,这是int数组的正确大小,但是在接收方,recvfrom返回0,尽管数组接收前两个整数元素,其余的是打印数组时的垃圾值。这是接收方的代码:

void get_data(int port, int coords[]){

    struct sockaddr_in si_other;

    int s, i; 
    char message[BUFLEN];

    if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
        err_print("socket");
    }

    memset((char*)&si_other, 0, sizeof(si_other));
    si_other.sin_family = AF_INET;

    si_other.sin_port = htons(port);
    si_other.sin_addr.s_addr = inet_addr(SERVER);

    if(inet_aton(SERVER, &si_other.sin_addr) == 0){
        fprintf(stderr, "inet_aton() failed\n");
        exit(1);
    }

    socklen_t slen = sizeof(si_other);


    int size = sizeof(coords);
    printf("Size: %d\n", size);
    int siz = 0;
    while(1)
    {
        printf("Enter message : ");
        strcpy(message, "coords");

        //send the message
        if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen)==-1)
        {
            err_print("sendto()");
        }

        //try to receive some data, this is a blocking call

        if (siz = (recvfrom(s, coords, 8, 0, (struct sockaddr *) &si_other, &slen)) == -1)
        {
            err_print("recvfrom()");
        }
        printf("Siz: %d\n", siz);

        break;
    }

    for(int j = 0; j<4; j++){
        printf("C: %d\n", coords[j]);
    }



    close(s);    

    return;
}

coords数组的输出位于接收端:1 2 4196592 0 现在,我想或许,整个数组都没有被发送,但是sendto返回的大小值是8,recvfrom的大小值是0,即使它得到前两个元素。另外,请注意在编译时,我收到sizeof的警告: 数组函数参数'coords'上的'sizeof'将返回'int *'

的大小

这里有什么问题,发送阵列的正确方法是什么?如果可能的话,还可以发送双数组吗?

1 个答案:

答案 0 :(得分:2)

这里的线索是问题中的主张是sizeof(coords),一个4元素int数组,结果是8。

当然,如果在这个实现中sizeof(int)是2,那只会是这种情况。我认为16位平台目前并不是闻所未闻,特别是在嵌入式领域。但后来又声称打印一个int也会产生4196592,当然不是两字节int的情况。

唯一的解释是这里给出的例子省略了关键信息。调用sendfrom()的代码不会直接访问coords数组。最有可能的是。coords数组作为参数传递给此函数。当然,它将它变成int *,其sizeof为8,导致只有前两个四字节int值通过套接字发送。这也是编译器警告的解释。

谁知道接收方会发生什么。