Hvordan sende struct og fakta om ACK

For å sende struct, er nesten som den måten dere pleier å sende char array eller peker med informasjon,

Men for å gjøre det lettvint og mer "struktur" så hadde det vært ok å få litt kjennskap til hvordan man sender struct.

(Istedenfor å måtte bruke strtok, strcat, sprintf etc).

 

Det første dere gjør er å ha en enkel struct:

 

#define MSG_SIZE 100

typedef struct {

int packet_number;
char frame[MSG_SIZE - sizeof(int)];

}packet;

Når dere tenker på pakker, tenk litt "objektorientert" hva bør en pakke inneholde?

(Dette er litt forenklet versjon, men det hadde vært rimelig med en header struct av hvilke type data dette var

(DATA eller ACK eller kanskje NACK?) og hvem det kunne vært til

 

deretter la oss se på sendern sin side:

int main() {

/*CODE LEFT OUT*/

packet *sendpacket;

int counter = 0;

/*you can choose to malloc or just allocate an array of 100 bytes  and cast it*/

char buffer[MSG_SIZE];

char read_buffer[MSG_SIZE];

sendpacket = (packet *)buffer;

memset(sendpacket,0,sizeof(packet));

bzero(&read_buffer,MSG_SIZE);

FILE *f = fopen(filename,"r");

while(fgets(read_buffer,MSG_SIZE,f) != NULL) {

sendpacket->pakkenr = htonl(counter);

strncpy(sendpacket->frame,read_buffer,MSG_SIZE);

send(socket_nr,(char *)sendpacket,MSG_SIZE,0);

counter++;

}

OK la dere merke til en ting? se nøye på sendpacket->pakkenr, hvorfor bruker jeg htonl?

Jo fordi vi vil gjerne sende datapakker på en riktig måte. Dvs at vi unngår

byte order problemet. Dette burde dere vurdere å bruke.

her er en fin link om forklaring på hton og ntoh fra Beej :)

ok nok om fakta, la oss gå til mottagerens side:

/*CODE LEFT OUT*/

char recvbuffer[MSG_SIZE];

int packet_number = -1;

packet *recvpacket;

memset(recvbuffer,0,MSG_SIZE);


recv(socket_nr,recvbuffer,MSG_SIZE,0);

recvbuffer[MSG_SIZE] = '\0'; /*not necessary I think...*/

recvpacket = (packet *)recvbuffer;

packet_number = ntohl(recvpacket->pakkenr);

/*replace the recvpacket->pakkenr data*/
recvpacket->pakkenr = packet_number

printf("PACKET NUMBER:  %d\n",packet_number);

printf("%s\n",recvbuffer);


/*should send back an ack but this is just an example, try to think for yourself how to do it :)*/

Det fins lettere måter å tenke seg frem til hvordan skille pakkene om det er data eller ack. For å spare plass,hadde det vært fint med litt bitshifting. En simpel tanke kunne være f.eks

#define ACK (1 << 6)

#define DATA (1 << 7)

/*CODE LEFT OUT*/

char type;
char recvbuffer[100];

/*CODE LEFT OUT*/

type = 0; /*set the type to 0*/

sendpacket->head->type | DATA;

/*send data etc*/

/*You should receive ackpacket here*/

recv(src,recvbuffer,----);
packet *returnpacket = (packet *)recvbuffer;

if(returnpacket->head->type&ACK)
 printf("OK WE GOT AN ACK FOR PACKET : %d\n",returnpacket->head->packet_number);


/*receiver's site*/

/*CODE LEFT OUT*/

if(sendpacket->head->type&DATA)
 printf("RETREIVED DATA FROM SENDER");

/*CODE LEFT OUT*/

returnpacket->head->type | ACK;

/*SEND PACKET BACK TO LET THE SENDER KNOW IT RECEIVED DATA*/

 

Ellers kunne dere brukt noe annet form, men for å spare plass, foreslår vi en char siden den bare er 1 byte.

Lykke til!

 

mvh Khiem-Kim Ho Xuan og Aage André Håland Dahl!



              
Publisert 25. jan. 2012 18:25 - Sist endret 28. aug. 2012 13:09