Here’s a simple code
for ftp client:
Step 1: Begin by
defining socket for opening a connection (ie for resolving host ip address and
port number)
struct hostent *he;
struct sockaddr_in clientaddr;
extern connection connC;
extern timer
t1[MAX_NUM_PACKETS];
extern sWindow window;
int sz, recAck,
req=0, temp, connid=0, ackNum, jj;
char
buffer[MAX_SRTP_STRING]="";
char
host_address[60]="";
char *quitCom = "quit";
char *put="put";
char *action;
char command[30]="";
char *filename;
srtp_header pkt;
char TONumber[10]="";
int compare=1, putcompare,namelength, pID, stimulus,ackIndex, rFlag, m,
i;
bool rtxflag, found, problem;
int
pp=pipe(pfd);
fcntl(pfd[0],F_SETFL,O_NONBLOCK);
done = 0;
initWindow(7); /*0418*/
struct sigaction act;
act.sa_handler = sig_chld;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_NOCLDSTOP;
if(sigaction(SIGCHLD,&act,NULL)<0)
printf("Chld sig error\n");
connC.currentState = CLOSED;
printf("Current State = %d\n",connC.currentState);
connC.host_addr.sin_family = AF_INET;
printf("HostName: ");
scanf("%s",host_address);
he
= gethostbyname(host_address);
if
(he==NULL)
{
printf("HOSTNAME ERROR!\n");
exit(1);
}
else
{
memcpy(&connC.host_addr.sin_addr, he->h_addr, he->h_length);
}
printf("PortNumber: ");
scanf("%d",&connC.portNumber);
connC.host_addr.sin_port = htons(connC.portNumber);
connC.connection_number = SRTP_Open((struct sockaddr
*)&connC.host_addr, connC.portNumber);
Step 2: Begin state
machine and establish 3-way handshake
if (connC.currentState != ESTABLISHED)
{
connC.connection_number = sendSynPkt();
startsyntimer();
if (connC.connection_number == 1)
{
connC.currentState = SYN_SENT;
printf("SYN
SENT!\n");
printf("Current
State: %d\n",connC.currentState);
printf("
Waiting for ACK and SYN from server\n");
}
else
{
printf("SYN
SEND ERROR!\n");
close(connC.socketDesc);
exit(1);
}
while (syntimer != 1)
{
recAck
= recvfrom(connC.socketDesc,buffer,MAX_SRTP_PACKET,0,(struct
sockaddr*)&connC.host_addr, &sz);
if
((recAck > 0) && (connC.currentState == SYN_SENT))
{
pkt = parser(buffer);
if (strcmp(pkt.contrl_field, SYN_ACK) == 0)
{
printf("RECEIVED A SYNACK!!!!!\n");
printf("Sending ACK for SYN_ACK from server\n");
req=1;
break;
}
}
}
}
if
(req != 1)
{
printf("Connection Timed out ! Retry later\n");
exit(1);
}
if
(c_sendAckPkt(100) == -1)
{
printf("Send ACK ERROR!");
connC.currentState = CLOSED;
close(connC.socketDesc);
exit(1);
}
else
{
printf("ACK SENT!\n\n");
connC.currentState = ESTABLISHED;
printf("Connection Established!\n");
}
Step 3: Connection is
established at this point to perform data transfer
do
{
if (syntimer==1) break;
}while(syntimer != 1);
gets(command);
while(compare != 0)
{
printf("\n");
printf("my_ftp> ");
gets(command);
while(int(command[0])==0)
{
printf("my_ftp>
");
gets(command);
}
action = strtok(command," ");
compare = strcmp(action,quitCom);
putcompare = strcmp(action,put);
while((putcompare!=0)&&(compare!=0))
{
printf("Command not found!\n");
printf("my_ftp> ");
for(int i=0;i<30;i++)
command[i]=0;
gets(command);
while(int(command[0])==0)
{
printf("my_ftp> ");
gets(command);
}
action = strtok(command," ");
compare = strcmp(action,quitCom);
putcompare = strcmp(action,put);
}
if(putcompare==0)
{
filename =
strtok(NULL,"\n");
namelength = strlen(filename);
printf("%s",filename);
int
fD, buff_size;
char
fileBuff[30000]="";
fD=open(filename,O_RDWR,0);
if
(fD==-1)
{
printf("check filename!\n");
close(fD);
}
else
{
strncpy(fileBuff," ",30000);
read(fD,fileBuff,30000);
close(fD);
buff_size = strlen(fileBuff);
printf("file read successfully\n");
if( (sendSetupPkt(filename, action, namelength) == -1) )
{
printf("Error in sending
setupPkt\n\n");
}
else
{
printf("Hoorray!! SetupPkt sent!!\n\n");
}
garb = 0;
conflag = 0;
timeout = 0;
rtxflag = false;
problem = false;
totalacks = 0;
initWindow(10);
initTimer();
char parentack[15]="",
childack[15]="";
//
======================================================================
// forking a listener process
//
========================================================================
switch(pID = fork())
{
case 0 :
printf("CHILD Listening for
ACKS\n");
for(;;)
{
int r =
recvfrom(connC.socketDesc,buffer,MAX_SRTP_STRING,0,(struct
sockaddr*)&connC.host_addr, &sz);
if ((r >
0)&&(int(buffer[0])!=0))
{
pkt = parser(buffer);
if ((strcmp(pkt.contrl_field, ACK)
== 0))
{
printf("CHILD RECEIVED DATA ACK :
%d\n", pkt.ack_num);
itoa(pkt.ack_num,childack);
write(pfd[1],childack,15);
for (int p=0;p<15;p++)
childack[p]=0;
}
for(int
p=0;p<(MAX_SRTP_STRING);p++)
{
buffer[p]=0;
if (p<15) childack[p]=0;
}
}
for(int
p=0;p<(MAX_SRTP_STRING);p++)
{
buffer[p]=0; if (p<15) childack[p]=0;}
}
default:
listenerprocessId = pID;
}
//=========================================================================
numPkts =
SRTP_Send(connC.connection_number,fileBuff,buff_size);
printf("numPkts: %d\n",numPkts);
if (numPkts
{
initWindow(numPkts);
window.start_index =0;
sendPackets(0,numPkts);
stimulus = numPkts;
rFlag = 0;
}
else
{ window.start_index =0;
sendPackets(0,window.window_size);
stimulus = window.window_size;
rFlag = 1;
}
while(totalacks != -1)
{
read(pfd[0],parentack,15);
jj = window.start_index;found = false;
while ((jj<(window.start_index +
window.window_size)) &&(!found))
{
if
((t1[jj].timed_out)&&(!t1[jj].ack_recd))
{
printf("Ack not received
and timeout on %d\n",jj);
found = true;
}
else
jj++;
}
if(found)
{
printf("ACK not received
so timeout\n");
for(int y=jj+1;
y<(window.start_index + window.window_size);y++)
{ kill(t1[y].pID,SIGSTOP); t1[y].timed_out
= 1;
printf("killed timer for pkt
%d\n",y);
}
window.start_index = jj;
stimulus = window.start_index
+ window.window_size;
printf("Resending %d to
%d\n", window.start_index, stimulus);
timeout =0;
if (conflag == 0)
{sendPackets(window.start_index,window.window_size);
}
else
{
conflag = 0;
problem = true;
totalacks = -1;
}
garb = 1;
rtxflag = 1;
}
if (int(parentack[0]) != 0)
{
ackNum = atoi(parentack);
ackIndex = ((ackNum-1)/80)-1;
printf("PARENT
RECEIVED ACK FOR: %d\n",ackIndex);
garb = 0;
if
(ackIndex >= 0)
{
if(t1[ackIndex].timed_out == 0)
{
kill(t1[ackIndex].pID, SIGSTOP);
t1[ackIndex].ack_recd = 1;
printf("Stoping Timer: %d\n",
t1[ackIndex].pID);
t1[ackIndex].pID = 0;
rtxflag = false;
totalacks++;
}
else if (t1[ackIndex].timed_out == 1)
printf("Packet %d TIMED OUT\n",
ackIndex);
}
if ((totalacks == numPkts) ||( ackNum
== 0))
{
rFlag = 0;
printf("ALL ACKS RECD\n");
totalacks = -1;
break;
}
for (int p=0;p<15;p++)
parentack[p]=0;
}
if ((ackIndex != (numPkts-1)) && (garb ==0))
{
rtxflag = false;
for(int
i=window.start_index;i
{
if((!rtxflag) && (ackIndex ==
(stimulus -1)) && (garb == 0))
{
printf("Present Window2 from %d to %d \n", window.start_index,
stimulus);
window.start_index = window.start_index +
window.window_size;
stimulus = window.start_index +
window.window_size;
timeout =0;
printf("Window2 slides to %d and
%d \n", window.start_index, stimulus);
sendPackets(window.start_index,window.window_size);
}
}
}
}
printf ("Out of while loop\n");
kill(listenerprocessId, SIGKILL);
/*0418*/
for (int r=0; r
if (t1[r].pID != 0)
kill(t1[r].pID, SIGSTOP);
initTimer();
printf("Done = %d\n", done);
while (done != 1) {}
if (problem == false)
printf("File Put Done! %d\n",numPkts);
else
printf("traffic problems ! You may want to try again\n");
for(i=0;i<30000;i++)
fileBuff[i] = 0;
done = 0;
}
}
}
Step 4: Connection
teardown with graceful disconnect
if((compare==0)&&(connC.currentState==ESTABLISHED))
{
printf("Goodbye!\n");
int d = SRTP_Close(connC.connection_number);
if(d)
connC.currentState = FIN_WAIT1;
}
if
(connC.currentState == FIN_WAIT1)
{
printf("WAITING FOR FINACK!\n");
for(;;)
{
int
r = recvfrom(connC.socketDesc,buffer,MAX_SRTP_PACKET,0,(struct
sockaddr*)&connC.host_addr, &sz);
if ((r>0)&&(int(buffer[0])!=0))
{
pkt = parser(buffer);
if (strcmp(pkt.contrl_field,FIN_ACK)==0)
{
printf("Received FINACK!\n");
connC.currentState = FIN_WAIT2;
int last =
SRTP_Close(connC.connection_number);
if (last)
connC.currentState = CLOSED;
}
}
if (connC.currentState == CLOSED)
exit(1);
}
}
return 0;
}