Reputation: 559
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
Upvotes: 0
Views: 2319
Reputation: 17332
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
Upvotes: 1
Reputation: 67802
That unpack code expects an int *
argument to unpack an int16_t
: change your declaration to int monkeycount;
Upvotes: 2