To Write FTP application, you will need to write the ftp server and the ftp client. The following illustrates the concepts for writing an FTP Server. In the following post, I will include the ftp client code.
Here’s a simple code
for an ftp server that uses UDP socket:
Step 1: Define
connection port number and create socket to listen on port number
int main()
{
extern connection connS;
char buffer[MAX_SRTP_PACKET+10]="";
extern incoming_buff server_buff[25];
int process_id, recSome, sz, cls, counter=0;
srtp_header srtp;
connS.currentState = CLOSED;
printf("Enter Port Number: ");
scanf("%d",&connS.portNumber);
Step 2: Initialize buffer for incoming client messages
initializeBuff();
while (connS.currentState != LISTEN)
connS.connection_number = SRTP_Listen(connS.portNumber);
if
(connS.currentState == LISTEN)
sz = sizeof(connS.host_addr);
Step 3: Set up handlers for signals and interrupts
struct sigaction act;
act.sa_handler = sig_chld;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_NOCLDSTOP;
if
(sigaction(SIGCHLD,&act,NULL)<0)
{
printf("CHILD SIGNAL ERROR\n");
return 1;
}
Step 4: Implement server state machine inside infinite loop
– server maintains state based on client response and messages to follow TCP
state change behavior (ie – this in turn makes UDP “behave” like TCP with SRTP
layer api)
for (;;)
{
recSome = recvfrom(connS.socketDesc, buffer,
MAX_SRTP_PACKET+10,0,(struct sockaddr *)&connS.host_addr, &sz);
if (recSome == -1)
{
}
else if (buffer != NULL)
{
srtp = parser(buffer);
if (connS.currentState == LISTEN)
{
if ( strcmp(srtp.contrl_field, SYN) ==
0)
{
connS.currentState = SYN_RECVD;
printf("*****SYN
RECEIVED!!!!!!!!\n");
synR = synTO= 0;
int temp =
SRTP_Listen(connS.portNumber);
}
}
else if (connS.currentState ==
SYN_RECVD)
{
if (strcmp(srtp.contrl_field, ACK) ==
0)
{
printf("SYN ACK
RECD!!\n");
connS.currentState=ESTABLISHED;
printf("CONNECTION
ESTBLISHED!\n");
}
}
else if (connS.currentState ==
ESTABLISHED)
{
printf("currentState
ESTABLISHED!!\n");
if (((strcmp(srtp.contrl_field, DAT))
== 0) || (strcmp(srtp.contrl_field, DATL) == 0))
{
printf("RECEIVING DATA PACKETS!!\n");
if (checksum(srtp)==srtp.cksum)
{
int inBuff=bufferPacket(srtp);
printf("In buff: %d\n",
inBuff);
if (inBuff==-1)
{
writeFile();
printf("FILE PUT DONE!\n");
}
}
}
else if
((strcmp(srtp.contrl_field,FIN))==0)
{
printf("FIN RECEIVED!");
synTimer(5);
connS.currentState = CLOSE_WAIT;
cls =
SRTP_Close(connS.connection_number);
if (cls)
connS.currentState = LAST_ACK;
}
else if
((strcmp(srtp.contrl_field,PUT))==0)
initializeBuff();
}
else if ((connS.currentState ==
LAST_ACK)||(finTO))
{
if (strcmp(srtp.contrl_field,ACK)==0)
{
finR=1;
printf("RECEIVED ACK ON
FIN\n");
printf("GOODBYE!\n");
connS.currentState = CLOSED;
}
}
else if (connS.currentState == CLOSED)
exit(1);
for (int f=0;f<
(MAX_SRTP_PACKET+10);f++)
buffer[f] = NULL;
}
if
((connS.currentState==LAST_ACK)&&(finTO))
connS.currentState=CLOSED;
if (connS.currentState == CLOSED)
{
printf("SO FAR: \n");
printf("%s\n",server_buff[0].pkt.data);
printf("%s\n",server_buff[1].pkt.data);
exit(1);
}
}
return 0;
}
Final Code: Here are all the includes and function
definitions prior to beginning main
void sig_chld(int);
static int Stimer, synR, synTO,finR,finTO,
maxPacket;
void synTimer(int amount)
{
synTO=finTO=0;
int processId;
processId = fork();
switch(processId)
{
case 0:
printf("FIN timer started!\n");
//usleep(amount);
sleep(amount);
printf("FIN
timer expired!\n");
_exit(0);
default:
Stimer = processId;
//return processId;
}
}
void sig_chld(int signo)
{
int status;
extern
connection connS;
waitpid(Stimer,&status,WNOHANG);
if(WIFEXITED(status))
{
synTO=1; finTO=1;
//if (!synR)
if (!finR)
{
connS.currentState = CLOSED;
printf("NO
FIN ACK RECEIVED!\n");
}
else printf("YOU WERE ACKED!\n");
}
return;
}
int bufferPacket(srtp_header srtp)
{
extern incoming_buff server_buff[25];
int index = (srtp.seq_num/80)-1;
if
(strcmp(srtp.contrl_field,DATL)==0)
{
maxPacket=index;
}
int tmp;
if
(!server_buff[index].received)
{ server_buff[index].pkt= srtp;
server_buff[index].received = 1;
printf("Storing packet # %d\n",index);
}
int i=0, ackNum;
while
((server_buff[i].received)&&(server_buff[i].ack_sent)&&(i<25))
i++;
if
(strcmp(server_buff[i-1].pkt.contrl_field,DATL)==0)
{ printf("ALL ACKS
SENT!\n");
return -1;
}
else if ((server_buff[i].received) &&(!server_buff[i].ack_sent))
{
ackNum = (i*80)+1;
tmp = s_sendAckPkt(ackNum);
server_buff[i].ack_sent = 1;
if (tmp)
printf("ACK SENT %d\n",ackNum);
return i;
}
}
void writeFile()
{
char tempBuff[2000];
int fileDesc;
printf("INSIDE WRITE FILE\n");
fileDesc = creat("testPut",448);
if
(fileDesc<0)
printf("File Exists!\n");
for (int t=0;t<25;t++)
{
write(fileDesc,server_buff[t].pkt.data,strlen(server_buff[t].pkt.data));
if (strcmp(server_buff[t].pkt.contrl_field,DATL)==0)
{
close(fileDesc);break;
}
}
return;
}
void initializeBuff()
{
for(int i=0;i<25;i++)
{ server_buff[i].received=0;
server_buff[i].ack_sent=0;
}
return;
}
No comments:
Post a Comment