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!