0
votes

I have for several hours tried, debugged and cried in hope to get my program to send/pack and receive/unpack my data correctly. My only hope is some good help!

To pack/unpack data i have implemented Beej's Guide to Network Programming example pack2.c

The code works pack/unpack works internally in the same program. But when i try to send the packed data over a socket to another program on the same computer, it will not work! My thoughts is that the recv() and send() functions in a way maybe makes the data corrupt or something like this, i have tried to debug this is several ways:

I need some help to get this working, i believe that the problem lays in the way buf is sent and received, since the pack()/unpack() functions work internally in a program.

Thanks

Client side:

unsigned char buf[1024];

    int16_t packetsize = pack(buf, "h", (int16_t)37);
    packi16(buf+1, packetsize);
    int len = packetsize;

    uint16_t header = htons(packetsize); //Convert from host -> network

    //Sends info to receiver about next pack coming.

    printf("HEADER SIZE %d\n", packetsize);

    if(send(sock, &header, packetsize, 0) == -1) {
        perror("sendall");
    }


    /*==========SEND PACKAGE======================*/

    int bytessendt = send(sock, buf, len, 0);//server_send_all(sock, buf, &len);

    if(bytessendt == -1) {
        perror("sendall");
    }

    printf("BYTES SENT OVER SOCKET: %d \n", bytessendt);


    close(sock);

Server side:

                uint16_t buf;
                int len = sizeof(buf);

                if(recv(i, &buf, len, 0) == -1) {
                    printf("****Error when receiving");
                }

                int header = ntohs(buf);

                printf("HEADER SIZE: %d\n", header);

                /*========REICIVE PACK AND UNPACK================*/

                unsigned char buf2[1024];
        int16_t monkeycount;

                int bytesreaded = recv(i, buf2, header, 0);

                if(bytesreaded == -1) {
                    printf("Feil ved mottakelse\n");
                }

                printf("BYTES READED: %d\n", bytesreaded);
                printf("BYTES SHOULD BE READED: %d\n", header);

                unpack(buf2, "h", &monkeycount);


                printf("CONTENT: %d\n", monkeycount);


                close(i);

int server_send_all(int socket, unsigned char *buf, int *len) {

    int total = 0;              //Total amout of data to send
    int bytesleft = *len;       //Amount of data left to send
    int n;                      //Holds return from send()

    printf("SOCKET -DATA TO SEND: %d\n", *len);

    while(total < *len) {
        n = send(socket, buf+total, bytesleft, 0);

        if(n == -1) { //send() returns error
            break;
        }

        total += n;
        bytesleft -= n;
    }

    *len = total; //Returns actually sent

    return n == -1?-1:0;
}

Sending string

From client:

int packetsize = 0;
packetsize += pack(buf + packetsize, "h", (int16_t)37);
packetsize += pack(buf + packetsize, "s", "Hello World");

    send(sock, &header, packetsize, 0) 

To server:

     char s2[30];
                        unpack(buf2, "h30s", &monkeycount, s2);                  

                        printf("CONTENT: %d %s\n", monkeycount, s2);

Gives output

CONTENT: 37 Hello Wor

2
What is the error ? what is the expected behaviour ? saying it won't work isn't enough.iabdalkader
The expected behavior is that printf("CONTENT: %d\n", monkeycount); should print 37, when unpacking monkeycount should hold 37. I believe that server_send_all() function takes care of sending all the data ?user265767
and what does it actually print?Useless
you're forgetting to increment the buf pointer again :)iabdalkader
Of course, I don't actually understand why we increase buf pointer :} The code now increments buf pointer, and the server side now removes the last two characters :(user265767

2 Answers

1
votes

you pack an int16_t which is 2 bytes and then you increment buf by 1 byte only, that should be 2 bytes instead:

int16_t packetsize = pack(buf, "h", (int16_t)37);
packi16(buf+2, packetsize);

Each time you pack something into the buffer you should increment the buffer pointer by that amount when calling pack() again:

pack(buf, 2 bytes);
pack(buf+2, 4 bytes);
pack(buf+6, 2 bytes);
...

So I think you should do it like this:

int packetsize =0;
packetsize += pack(buf+packetsize, "h", (int16_t)37);
packetsize += pack(buf+packetsize, "h", (int16_t)38);
...

Note1: packetsize should be an int as pack() returns an int, and I don't see why you use packi16() the second time instead of the more generic pack() function.

Note2: Also the packet size is wrong, you forgot to add the size of packetsize. in fact, I don't think you mean to add the packet size to the packet at all, because you're sending the packet size and the packet separately

2
votes

That unpack code expects an int * argument to unpack an int16_t: change your declaration to int monkeycount;