文件传输协议的简单设计与实现(c语言,VC6.0)
/****************server.c****************/
#include
#include
#include
#pragma comment(lib,"ws2_32.lib")
WSADATA wsd;
char sbuffer[80],rbuffer[80];//send and receive buffers
int n,bytes;//counters
SOCKET newsocket,ns_data;
struct sockaddr_in remoteaddr; //remoteaddr_data;
int port_connect=0;//port connect flag
char path[80]="";
char order[100]="";
//SOCKET s_data_port;
int sy_error=1; // use for indicate Syntax error
//server functions
int sdirfun(SOCKET newsocket);
int sgetfun(SOCKET newsocket);
int sputfun(SOCKET newsocket);
int spwdfun(SOCKET newsocket);
int scdfun(SOCKET newsocket);
int smdfun(SOCKET newsocket);
int sdelfun(SOCKET newsocket);
void HandleError(char *func);
//server functions end
//MAIN
int main(int argc, char *argv[])
{
struct sockaddr_in localaddr;//local address structure
SOCKET s;//s_data;//welcome socket and welcome socket for data connection,and port connection for connect to client
int addr_inlen;//address lenght variable
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
WSACleanup();
printf("WSAStartup failed/n");
}
memset(&localaddr,0,sizeof(localaddr));//clear localaddr
s = socket(PF_INET, SOCK_STREAM, 0);
if (s <0)
{
printf("socket failed/n");
}
localaddr.sin_family = AF_INET;
if(argc == 2)
localaddr.sin_port = htons((u_short)atoi(argv[1]));
else
localaddr.sin_port = htons(2302);
localaddr.sin_addr.s_addr = INADDR_ANY;
if (bind(s,(struct sockaddr *)(&localaddr),sizeof(localaddr)) < 0)
{
printf("Bind failed!/n");
}
//INFINITE LOOP
while (1)
{ // while loop 1
//LISTEN
listen(s,3);
addr_inlen = sizeof(remoteaddr);
//ACCEPT main connection (control connection)
newsocket = accept(s,(struct sockaddr *)(&remoteaddr),&addr_inlen);
if (newsocket == INVALID_SOCKET) break;
printf("connected to %s at port %d /n",inet_ntoa(remoteaddr.sin_addr),ntohs(localaddr.sin_port));
//Respond with welcome message, FTP client requires those
sprintf(sbuffer,"200 Welcome /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
sprintf(sbuffer,"530 Log in /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
//INFINITE LOOP
while (1) // while loop 2
{
n = 0;
sy_error=1;
while (1) // while loop 3
{
//RECEIVE
bytes = recv(newsocket, &rbuffer[n], 1, 0);
printf("rbuffer[%d]=%c/n",n,rbuffer[n]);
if ((bytes < 0) || (bytes == 0))
break;
if (rbuffer[n] == '$')
{
rbuffer[n] = '/0';
break;
}
if (rbuffer[n] != '/r')
n++;
} // end of while loop 3
if ((bytes < 0) || (bytes == 0))
break;
printf("#The Server receives:# '%s' from client /n", rbuffer);
//THE FTP COMMANDS HERE
//LIST
if(strncmp(rbuffer,"dir",3)==0)
{
sdirfun(newsocket);
}
//当前目录
if(strncmp(rbuffer,"pwd",3)==0)
{
spwdfun(newsocket);
}
//改变目录
if (strncmp(rbuffer,"cd",2)==0)
{
scdfun(newsocket);
}
//GET
if (strncmp(rbuffer,"get",3)==0)
{
sgetfun(newsocket);
}
//PUT
if (strncmp(rbuffer,"put",3)==0)
{
sputfun(newsocket);
}
//MD
if (strncmp(rbuffer,"md",2)==0)
{
smdfun(newsocket);
}
if (strncmp(rbuffer," del ",3)==0)
{
sdelfun(newsocket);
}
//QUIT
if (strncmp(rbuffer,"quit",4)==0)
{
printf("quit /n");
sprintf(sbuffer, "221 Bye bye ... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
sy_error=0;
break;
}
//Syntax error
if (sy_error==1)
{
printf("command unrecognized, non-implemented!/n");
sprintf(sbuffer, "500 Syntax error. /n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
}
} // end of while loop 2
//CLOSE CONTROL SOCKET
closesocket(newsocket);
printf("disconnected from %s at port %d, close control socket./n",inet_ntoa(remoteaddr.sin_addr),ntohs(localaddr.sin_port));
} // end of while loop 1
//CLOSE WELCOME SOCKET
closesocket(s);
printf("Welcome sockets close");
return 0;
}
int sdirfun(SOCKET newsocket)
{
char temp_buffer[80];
printf("Equivalent to dir /n");
order[0]='/0';
strcat(order,"dir ");
strcat(order,path);
strcat(order," >tmp.txt");
system(order);
FILE *fin;
fin=fopen("tmp.txt","r");
sprintf(sbuffer, "125 Transfering... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
while (fgets(temp_buffer,80,fin)!=NULL)
{
sprintf(sbuffer,"%s",temp_buffer); //
if (port_connect==0)
send(newsocket, sbuffer, strlen(sbuffer), 0);
}
fclose(fin);
sprintf(sbuffer, "226 Transfer completed... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
system(" del tmp.txt");
//CLOSE the ns_data SOCKET or data port SOCKET
if(port_connect==0)
{
closesocket(ns_data);
sprintf(sbuffer,"226 Close the data socket... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
ns_data = socket(AF_INET, SOCK_STREAM, 0);
}
sy_error=0;
return 0;
}
int sgetfun(SOCKET newsocket)
{
printf("RETR mode./r/n");
int i=4,k=0;
char filename[20],temp_buffer[80];
// identify the filename from rbuffer after the word "RETR "
while (1) // while loop 4
{
//RECEIVE
bytes = recv(newsocket, &rbuffer[i], 1, 0);
printf("rbuffer[i]=%c/n",rbuffer[i]);
if ((bytes < 0) || (bytes == 0))
break;
filename[k]=rbuffer[i];
if (rbuffer[i] == '/0')
{ /*end on LF*/
filename[k] = '/0';
break;
}
if (rbuffer[i] != '/r')
{
i++;
k++;/*ignore CR's*/
}
} // end of while loop 4
order[0]='/0';
strcat(order,path);
if(strlen(path)>0)
strcat(order,"//");
strcat(order,filename);
char *p_filename=order;
FILE *fp;
if( (fp=fopen(p_filename,"r")) == NULL )
{
sprintf(sbuffer, "Sorry, cannot open %s. Please try again./r/n",filename);
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
sprintf(sbuffer, "226 Transfer completed... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
return 1;
}
else
{
printf("The file %s found,ready to transfer./n",filename);
sprintf(sbuffer, "125 Transfering... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
while (fgets(temp_buffer,80,fp)!=NULL)
{
sprintf(sbuffer,"%s",temp_buffer); //
if (port_connect==0)
send(newsocket, sbuffer, strlen(sbuffer), 0);
}//end of while
fclose(fp);
sprintf(sbuffer, "226 Transfer completed... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
}
sy_error=0;
return 0;
}
int sputfun(SOCKET newsocket)
{
printf("Equivalent to put. /n");
int i=4,k=0;
char filename[20];
// identify the filename from rbuffer after the word "RETR "
while (1)
{
bytes = recv(newsocket, &rbuffer[i], 1, 0);
if ((bytes < 0) || (bytes == 0))
break;
filename[k]=rbuffer[i];
if (rbuffer[i] == '/0')
{ /*end on LF*/
filename[k] = '/0';
break;
}
if (rbuffer[i] != '/r')
{
i++;
k++;/*ignore CR's*/
}
} // end of while
order[0]='/0';
strcat(order,path);
if(strlen(path)>0)
strcat(order,"//");
strcat(order,filename);
printf("filename=%s,",order);
char *p_filename=order;
FILE *fpse;
if( (fpse=fopen(order,"w")) == NULL )
{
printf("open errer");
return 1;
}
else
{
printf("The file %s found,ready to transfer./n",filename);
while(1)
{
//读取流并显示
int ret;
ret = recv(newsocket, rbuffer, 80, 0);
if (ret == 0) // Graceful close
return 0;
else if (ret == SOCKET_ERROR)
{
printf("recv() failed: %d/n", WSAGetLastError());
return 0;
}
if(strncmp(rbuffer,"226 Transfer",strlen("226 Transfer"))==0)
{
break;
}
fprintf(fpse,"%s",rbuffer);
}
printf("RBUFFER=%s",rbuffer);
fclose(fpse);
}
sy_error=0;
return 0;
}
int spwdfun(SOCKET newsocket)
{
printf("Equivalent to pwd /n");
//order[0]='/0';
//strcat(order,"dir ");
//strcat(order,path);
//strcat(order,);
system("cd >tmp.txt");
FILE *fin;
fin=fopen("tmp.txt","r+");
sprintf(sbuffer, "125 Transfering... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
char temp_buffer[160];
while (fgets(temp_buffer,80,fin)!=NULL)
{
temp_buffer[strlen(temp_buffer)-1]='/0';
printf("temp_buffer=%s",temp_buffer);
///目录判定
if(path[0]!='/0')
sprintf(sbuffer,"%s//%s",temp_buffer,path);
else
sprintf(sbuffer,"%s",temp_buffer);
///
if (port_connect==0)
//send(ns_data, sbuffer, strlen(sbuffer), 0);
send(newsocket, sbuffer, strlen(sbuffer), 0);
}
fclose(fin);
sprintf(sbuffer, "226 Transfer completed... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
system(" del tmp.txt");
//CLOSE the ns_data SOCKET or data port SOCKET
if(port_connect==0)
{
closesocket(ns_data);
sprintf(sbuffer,"226 Close the data socket... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
ns_data = socket(AF_INET, SOCK_STREAM, 0);
}
sy_error=0;
return 0;
}
int scdfun(SOCKET newsocket)
{
int i=3,k=0;char name[20],name2[20];
int j,count=0;//path overfollow
int pathlen;
printf("Equivalent to cd /n");
while (1)
{
//RECEIVE
bytes = recv(newsocket, &rbuffer[i], 1, 0);
printf("rbuffer[i]=%c/n",rbuffer[i]);
printf("bytes=%d/n",bytes);
if ((bytes < 0) || (bytes == 0))
break;
name[k]=rbuffer[i];
name2[k]=rbuffer[i];
if (rbuffer[i] == '/0')
{
name[k] = '/0';
name2[k] = '/0';
break;
}
if (rbuffer[i] != '/r')
{
i++;
k++;
}
}//end while
if(path[0]!='/0')
strcat(path,"//");
strcat(path,name);
if(strncmp(name2,"..",2)==0)
{
pathlen=strlen(path);
for(j=pathlen-1;j>=0;j--)
{
if(path[j]=='//')
{
path[j]='/0';
count++;
}
if(count==2)
{
//path[j]='/0';
break;
}
}
printf("%d=/n",j);
path[j+1]='/0';
}
printf("path=%s",path);
sy_error=0;
return 0;
}
int smdfun(SOCKET newsocket)
{
char name[20];
int i=3,k=0;
printf("Equivalent to md /n");
while (1) // while loop 3
{
//RECEIVE
bytes = recv(newsocket, &rbuffer[i], 1, 0);
printf("rbuffer[i]=%c/n",rbuffer[i]);
printf("bytes=%d/n",bytes);
if ((bytes < 0) || (bytes == 0))
break;
name[k]=rbuffer[i];
if (rbuffer[i] == '/0')
{ /*end on LF*/
name[k] = '/0';
break;
}
if (rbuffer[i] != '/r')
{
i++;
k++;/*ignore CR's*/
}
}
order[0]='/0';
strcat(order,"md ");
strcat(order,path);
if(strlen(path)>0)
strcat(order,"//");
strcat(order,name);
system(order);
//CLOSE the ns_data SOCKET or data port SOCKET
if(port_connect==0)
{
//closesocket(ns_data);
sprintf(sbuffer,"226 Close the data socket... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
//ns_data = socket(AF_INET, SOCK_STREAM, 0);
}
sy_error=0;
return 0;
}
int sdelfun(SOCKET newsocket)
{
int i=3,k=0;char name[20];
printf("Equivalent to del /n");
while (1)
{
//RECEIVE
bytes = recv(newsocket, &rbuffer[i], 1, 0);
printf("rbuffer[i]=%c/n",rbuffer[i]);
printf("bytes=%d/n",bytes);
if ((bytes < 0) || (bytes == 0))
break;
name[k]=rbuffer[i];
if (rbuffer[i] == '/0')
{
name[k] = '/0';
break;
}
if (rbuffer[i] != '/r')
{
i++;
k++;
}
}//end while
order[0]='/0';
strcat(order,"rd ");
strcat(order,path);
if(path[0]!='/0')
strcat(path,"//");
strcat(order,name);
system(order);
sprintf(sbuffer," del ok... /r/n");
bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);
if (bytes == SOCKET_ERROR)
{
HandleError("recv()");
sy_error=1;
return 1;
}
sy_error=0;
return 0;
}
void HandleError(char *func)
{
char info[65]= {0};
_snprintf(info, 64, "%s: %d/n", func, WSAGetLastError());
printf(info);
}