gpt4 book ai didi

用 C 代码编写基于 TCP 的 FTP 服务

转载 作者:可可西里 更新时间:2023-11-01 02:44:55 25 4
gpt4 key购买 nike

我正在尝试为多线程服务器编写 TCP FTP 服务。我找到了这个教程 http://www.mario-konrad.ch/wiki/doku.php?id=programming:multithreading:tutorial-04这对理解TCP协议(protocol)的客户端多线程非常有帮助。事实上,这段代码创建了一个可以同时接受来自不同客户端的多个连接的服务器。

但是,我正在努力寻找如何在其上应用 ftp 服务。精确地说明如何向 FTP 服务器发送文件和从 FTP 服务器获取文件。

有什么帮助吗?

最佳答案

下面的代码是我去年为一篇网络论文所做的作业。希望对您有所帮助。

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <winsock.h>
#include <winsock2.h>

#define BUFFERSIZE 800
#define WSVERS MAKEWORD(2,0)

WSADATA wsadata;
void wy_fileName_collector(char *_buffer, char *_nameBuffer);
int main(int argc, char *argv[])
{
//INITIALIZATION
struct sockaddr_in localaddr,remoteaddr;
struct sockaddr_in remoteaddr_act;

SOCKET s,ns;
SOCKET s_data_act=0;

char send_buffer[BUFFERSIZE],receive_buffer[BUFFERSIZE];
char fileName[40];


int n,bytes,addrlen;
memset(&localaddr,0,sizeof(localaddr));//clean up the structure
memset(&localaddr,0,sizeof(remoteaddr));//clean up the structure

//WSASTARTUP
if (WSAStartup(WSVERS, &wsadata) != 0)
{
WSACleanup();
printf("WSAStartup failed\n");
exit(1);
}

//SOCKET
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(1234);//default listening port
localaddr.sin_addr.s_addr = INADDR_ANY;//server address should be local

//BIND
if (bind(s,(struct sockaddr *)(&localaddr),sizeof(localaddr)) != 0)
{
printf("Bind failed!\n");
exit(0);
}

//LISTEN
listen(s,5);

while (1)
{
addrlen = sizeof(remoteaddr);

//NEW SOCKET newsocket = accept
ns = accept(s,(struct sockaddr *)(&remoteaddr),&addrlen);
if (ns <0 ) break;
printf("accepted a connection from client IP %s port %d \n",inet_ntoa(remoteaddr.sin_addr),ntohs(localaddr.sin_port));

//Respond with welcome message
sprintf(send_buffer,"\n==220 Welcome to Alan's FTP site== \r\n\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);

while (1)
{
n = 0;
while (1)
{
//RECEIVE
bytes = recv(ns, &receive_buffer[n], 1, 0);//receive byte by byte...

//PROCESS REQUEST
if ( bytes <= 0 ) break;
if (receive_buffer[n] == '\n')
{ /*end on a LF*/
receive_buffer[n] = '\0';
break;
}
if (receive_buffer[n] != '\r') n++; /*ignore CRs*/
}
if ( bytes <= 0 ) break;

printf("-->DEBUG: the message from client reads: '%s' \r\n", receive_buffer);

/**
* @brief Exception handling
*/
if(strncmp(receive_buffer,"USER",4) && strncmp(receive_buffer,"PASS",4) && strncmp(receive_buffer,"SYST",4)
&&strncmp(receive_buffer,"PORT",4) && strncmp(receive_buffer,"STOR",4) && strncmp(receive_buffer,"RETR",4)
&&strncmp(receive_buffer,"LIST",4) && strncmp(receive_buffer,"NLST",4) && strncmp(receive_buffer,"QUIT",4))
{
sprintf(send_buffer,"202 Command not implemented, superfluous at this site. \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
}


if (strncmp(receive_buffer,"USER",4)==0)
{
printf("Logging in \n");
sprintf(send_buffer,"331 Password required \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
if (bytes < 0) break;
}

if (strncmp(receive_buffer,"PASS",4)==0)
{
printf("Typing password (anything will do... \n");
sprintf(send_buffer,"230 Public login sucessful \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
if (bytes < 0) break;
}

if (strncmp(receive_buffer,"SYST",4)==0)
{
system("ver > tmp.txt");

FILE *fin=fopen("tmp.txt","r");//open tmp.txt file
sprintf(send_buffer,"150 Transfering... \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
char temp_buffer[80];
while (!feof(fin))
{
fgets(temp_buffer,78,fin);
sprintf(send_buffer,"%s",temp_buffer);
send(s_data_act, send_buffer, strlen(send_buffer), 0);
}
fclose(fin);
sprintf(send_buffer,"226 File transfer completed... \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);

if (bytes < 0) break;
}

//PORT
if(strncmp(receive_buffer,"PORT",4)==0)
{
s_data_act = socket(AF_INET, SOCK_STREAM, 0);
//local variables
unsigned char act_port[2];
int act_ip[4], port_dec;
char ip_decimal[40];
sscanf(receive_buffer, "PORT %d,%d,%d,%d,%d,%d",&act_ip[0],&act_ip[1],&act_ip[2],&act_ip[3],(int*)&act_port[0],(int*)&act_port[1]);
remoteaddr_act.sin_family=AF_INET;//local_data_addr_act
sprintf(ip_decimal, "%d.%d.%d.%d", act_ip[0], act_ip[1], act_ip[2],act_ip[3]);
printf("IP is %s\n",ip_decimal);
remoteaddr_act.sin_addr.s_addr=inet_addr(ip_decimal);
port_dec=act_port[0]*256+act_port[1];
printf("port %d\n",port_dec);
remoteaddr_act.sin_port=htons(port_dec);

if (connect(s_data_act, (struct sockaddr *)&remoteaddr_act, (int) sizeof(struct sockaddr)) != 0)
{
printf("trying connection in %s %d\n",inet_ntoa(remoteaddr_act.sin_addr),ntohs(remoteaddr_act.sin_port));
sprintf(send_buffer, "425 Something is wrong, can't start the active connection... \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);

closesocket(s_data_act);
}
else
{
sprintf(send_buffer, "200 Ok\r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
printf("Data connection to client created (active connection) \n");
}
}

/**
* @brief STOR
*/
if((strncmp(receive_buffer,"STOR",4)==0))
{
memset(&fileName, 0, strlen(fileName));
wy_fileName_collector(receive_buffer, fileName);

if(fopen(fileName,"w") == NULL)
{
printf("@alan:line1\n");
sprintf(send_buffer,"450 Requested file action not taken. \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
}
else
{
FILE *fout=fopen(fileName,"w");

sprintf(send_buffer,"150 File status okay; about to open data connection. \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
while(1)
{
n = 0;
while(1)
{
//RECEIVE
bytes = recv(s_data_act, &receive_buffer[n], 1, 0);//receive byte by byte...
//PROCESS REQUEST
if ( bytes <= 0 ) break;

if (receive_buffer[n] == '\n')
{ /*end on a LF*/
receive_buffer[n] = '\0';
break;
}

if (receive_buffer[n] != '\r') n++; /*ignore CRs*/
}
if ( bytes <= 0 ) break;
fprintf(fout,"%s\n",receive_buffer);
}

sprintf(send_buffer,"226 File transfer completed... \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);

fclose(fout);
closesocket(s_data_act);
}
}

/**
* @brief RETR
*/
if((strncmp(receive_buffer,"RETR",4)==0))
{
memset(&fileName, 0, strlen(fileName));
wy_fileName_collector(receive_buffer, fileName);

if(fopen(fileName,"r")==NULL)
{
sprintf(send_buffer,"450 Requested file action not taken. \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
}
else
{
FILE *fin=fopen(fileName,"r");//open tmp.txt file
sprintf(send_buffer,"150 Transfering... \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
char temp_buffer[80];
while (!feof(fin))
{
fgets(temp_buffer,78,fin);
sprintf(send_buffer,"%s",temp_buffer);
send(s_data_act, send_buffer, strlen(send_buffer), 0);
}
fclose(fin);
sprintf(send_buffer,"226 File transfer completed... \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
}
closesocket(s_data_act);
}



//LIST or NLST
if ( (strncmp(receive_buffer,"LIST",4)==0) || (strncmp(receive_buffer,"NLST",4)==0))
{
system("dir > tmp.txt");

FILE *fin=fopen("tmp.txt","r");//open tmp.txt file
sprintf(send_buffer,"150 Transfering... \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
char temp_buffer[80];
while (!feof(fin))
{
fgets(temp_buffer,78,fin);
sprintf(send_buffer,"%s",temp_buffer);
send(s_data_act, send_buffer, strlen(send_buffer), 0);
}
fclose(fin);
sprintf(send_buffer,"226 File transfer completed... \r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);

closesocket(s_data_act);
}


//QUIT
if (strncmp(receive_buffer,"QUIT",4)==0)
{
printf("Quit \n");
sprintf(send_buffer,"221 Connection closed by the FTP client\r\n");
bytes = send(ns, send_buffer, strlen(send_buffer), 0);
if (bytes < 0) break;
closesocket(ns);
}
}
//CLOSE SOCKET
closesocket(ns);
printf("disconnected from %s\n",inet_ntoa(remoteaddr.sin_addr));
}
closesocket(s);//it actually never gets to this point....use CTRL_C
}

/**
* @brief Return file name from the string passed in.
*/
void wy_fileName_collector(char *_buffer, char *_nameBuffer)
{
char bf[BUFFERSIZE];
char sep[2] = " "; //separation is space
char *word;
int wcount=0;

strcpy(bf, _buffer);
for (word = strtok(bf, sep);word;word = strtok(NULL, sep))
{
wcount++;
if(wcount == 2) // jump the first space"_".
{
strcpy(_nameBuffer, word);
}
}
}

关于用 C 代码编写基于 TCP 的 FTP 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23119615/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com