/* simulates 2 concurrent tftp clients */ #include /* standard C i/o facilities */ #include /* needed for atoi() */ #include /* defines STDIN_FILENO, system calls,etc */ #include /* system data type definitions */ #include /* socket specific definitions */ #include /* INET constants and stuff */ #include /* IP address conversion stuff */ #include /* gethostbyname */ #include #include "support.h" int waitandack(int num,int sk, struct sockaddr_in *s,int bnum) { char buff[1000]; int len; int opcode,block; if ((len=wait_for_response(sk,s,buff,1000))==0) { printf("No Response from client %d\n",num); return(0); } opcode = get_opcode(buff); block = get_blocknum(buff); if ((opcode != DATA) || (block != bnum)) { printf("Invalid (not what I expected!) from client %d\n",num); return(0); } printf("Got block %d (%d) from client %d\n",block,len,num); build_ack(buff,block); if (sendto(sk,buff,4,NULL,(struct sockaddr*)s,sizeof(*s))<0) { perror("Error sending"); return(0); } printf("Sending ACK for block %d (from client %d): ",block,num); print_msg(buff,4); return(len); } void multifiletransfer(int sk,int sk2, struct sockaddr_in *s, char *filename) { int sent; char buff[1000]; int len; int bnum=1; int bnum2=1; struct sockaddr_in s1,s2; memcpy(&s1,s,sizeof(*s)); memcpy(&s2,s,sizeof(*s)); len = build_request(buff,RRQ,filename,"octet"); printf("Sending RRQ (from client 1): "); print_msg(buff,len); sent = sendto(sk,buff,len,NULL,(struct sockaddr*)&s1,sizeof(*s)); printf("Sending RRQ (from client 2): "); print_msg(buff,len); sent = sendto(sk2,buff,len,NULL,(struct sockaddr*)&s2,sizeof(*s)); while (1) { if ( (len=waitandack(1,sk,&s1,bnum))==0) { printf("Error with client 1\n"); return; } if ( (len=waitandack(2,sk2,&s2,bnum2))==0) { printf("Error with client 2\n"); return; } if (len!=516) { printf("MULTICLIENT: OK\n"); break; } bnum++; bnum2++; } } /* client program: The following must passed in on the command line: hostname of the server (argv[1]) port number of the server (argv[2]) file name (argv[3]) */ int main( int argc, char **argv ) { int sk,sk2; struct sockaddr_in server; struct hostent *hp; /* Make sure we have the right number of command line args */ if (argc!=4) { printf("Usage: %s \n",argv[0]); exit(0); } /* create a socket IP protocol family (PF_INET) UDP (SOCK_DGRAM) */ if ((sk = socket( PF_INET, SOCK_DGRAM, 0 )) < 0) { printf("Problem creating socket\n"); exit(1); } if ((sk2 = socket( PF_INET, SOCK_DGRAM, 0 )) < 0) { printf("Problem creating socket\n"); exit(1); } server.sin_family = AF_INET; if ((hp = gethostbyname(argv[1]))==0) { printf("Invalid or unknown host\n"); exit(1); } /* copy the IP address into the sockaddr It is already in network byte order */ memcpy( &server.sin_addr.s_addr, hp->h_addr, hp->h_length); /* establish the server port number - we must use network byte order! */ server.sin_port = htons(atoi(argv[2])); multifiletransfer(sk,sk2,&server,argv[3]); return(0); }