一个FTP客户的简单的代码流程+简要总结分析

 花了将近两天分析了一个1500行的FTP代码,又查阅了RFC文挡等。学习了很多东西。
组长突然通知不用FTP了,  
这里把FTP大概的一个SOCKET方式整理一下,以备以后学习使用
总的来说流程就是:
FTP分两个TCP连接,一个是控制流,一个是数据流
命令流比如是登陆啊,帮助,退出啊之类的
数据流进行数据的传输,使用的是另外的端口,如果不指定,默认用21。具体可查看RFC文档

与FTP服务器交互的流程
发送 命令格式过去,等待服务器返回,然后判断返回代码,再发
如果涉及到数据的话,有两种方式,pasv 和port
port:客户端告诉服务端使用的端口,等待服务器主动链接
pasv:由服务器告诉客户端端口,由客户端主动链接。
差别:假设客户端是在内网,那么服务器是过不了的。所以经常用公网的服务器去链接内网或者公网的客户端。

  #include <iostream>   
  1. #include <winsock2.h>   
  2.   
  3. #pragma comment(lib, "Ws2_32")   
  4.   
  5. using namespace std;   
  6.   
  7. int main(int argc, char **argv)   
  8. {   
  9.     char session_tmp[1024];   
  10.     int timeout = 10;   
  11.     unsigned short port = 21;   
  12.     char *ip = "192.168.0.238";   
  13.   
  14.     struct sockaddr_in addr_client;   
  15.     SOCKET socket_fd;   
  16.   
  17.     int err;   
  18.     WSADATA wsaData;   
  19.     err = WSAStartup(0x0202, &wsaData );   
  20.     if ( err != 0 )    
  21.     {   
  22.         {   
  23.             cout<<"[-] WSAStartup"<<endl;   
  24.         }                                    
  25.     }   
  26.   
  27.   
  28.     if( (socket_fd = socket(AF_INET,SOCK_STREAM,0)) == -1)   
  29.     {   
  30.         cout<<"[-] socket"<<endl;   
  31.         return -1;   
  32.     }   
  33.     setsockopt(socket_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int));   
  34.     setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int));   
  35.   
  36.     addr_client.sin_family=AF_INET;   
  37.     addr_client.sin_port = htons(port);   
  38.     addr_client.sin_addr.S_un.S_addr = inet_addr(ip);   
  39.   
  40.     if( connect(socket_fd, (struct sockaddr*)&addr_client, sizeof(sockaddr)) ==-1 )   
  41.     {   
  42.         cout<<"[-] connect"<<endl;   
  43.         return -1;   
  44.     }   
  45.   
  46.     int data_len;   
  47.   
  48.     data_len = recv(socket_fd, session_tmp, 10240);   
  49.   
  50.     if( SOCKET_ERROR==data_len )   
  51.     {   
  52.         cout<<"[-] recv"<<GetLastError()<<endl;   
  53.         return -1;   
  54.     }   
  55.     session_tmp[data_len] = '\0';   
  56.     cout<<session_tmp<<endl;   
  57.        
  58.     char name[10];   
  59.     char passwd[10];   
  60.     cout<<"name:";   
  61.     scanf("%s", name);   
  62.     cout<<endl;   
  63.   
  64.     //   
  65.     _snprintf(session_tmp, sizeof(session_tmp), "USER %s\r\n",   
  66.               name);   
  67.     data_len=send(socket_fd, session_tmp, strlen(session_tmp), 0);   
  68.     data_len=recv(socket_fd, session_tmp, 10240);   
  69.        
  70.     session_tmp[data_len]='\0';   
  71.     cout<<endl;   
  72.     cout<<session_tmp<<endl;   
  73.     //end    
  74.   
  75.     //   
  76.     cout<<"passwd:";   
  77.     scanf("%s", passwd);   
  78.   
  79.     _snprintf(session_tmp, sizeof(session_tmp), "PASS %s\r\n",   
  80.               passwd);   
  81.   
  82.     data_len=send(socket_fd, session_tmp, strlen(session_tmp), 0);   
  83.     data_len=recv(socket_fd, session_tmp, 10240);   
  84.   
  85.     session_tmp[data_len]='\0';   
  86.     cout<<endl;   
  87.     cout<<session_tmp<<endl;   
  88.     //end    
  89.   
  90.     //ls port,client listen on a port and wait the server to connect.  
  91.     //组织好IP地址和端口号   
  92.     //用port的话,发送port命令   
  93.     //用ls查看,发送ls命令   
  94.     //accept服务器连接   
  95.     //recv。接受服务器传来的消息   
  96.   
  97.     WSACleanup();   
  98.   
  99.   
  100.     return 0;      
  101. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的Python实现FTP服务器的示例代码: ```python import socket import os HOST = '127.0.0.1' # FTP服务器IP地址 PORT = 21 # FTP服务器端口号 BACKLOG = 5 # 最大连接数 BUFSIZE = 1024 # 缓冲区大小 # 获取当前工作目录 def pwd(): return os.getcwd() # 列出当前目录下的文件列表 def dir_list(): return os.listdir() # 切换工作目录 def cwd(path): os.chdir(path) # 下载文件 def retr(filename): with open(filename, 'rb') as f: data = f.read() return data # 上传文件 def stor(filename, data): with open(filename, 'wb') as f: f.write(data) # 处理客户端请求 def handle_request(conn): conn.send(b'220 Welcome to FTP server.\r\n') while True: data = conn.recv(BUFSIZE) if not data: break cmd = data.decode().strip() if cmd == 'QUIT': conn.send(b'221 Goodbye.\r\n') break elif cmd == 'PWD': conn.send(bytes('257 "%s"\r\n' % pwd(), 'utf-8')) elif cmd == 'LIST': files = dir_list() conn.send(b'150 Here comes the directory listing.\r\n') for f in files: conn.send(bytes(f + '\r\n', 'utf-8')) conn.send(b'226 Directory send OK.\r\n') elif cmd.startswith('CWD '): path = cmd[4:] cwd(path) conn.send(bytes('250 Directory changed to "%s"\r\n' % path, 'utf-8')) elif cmd.startswith('RETR '): filename = cmd[5:] data = retr(filename) conn.send(b'150 Opening data connection.\r\n') conn.send(data) conn.send(b'226 Transfer complete.\r\n') elif cmd.startswith('STOR '): filename = cmd[5:] conn.send(b'150 Opening data connection.\r\n') data = conn.recv(BUFSIZE) stor(filename, data) conn.send(b'226 Transfer complete.\r\n') else: conn.send(b'500 Unknown command.\r\n') conn.close() # 创建TCP套接字 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((HOST, PORT)) sock.listen(BACKLOG) print('FTP server listening on port %d...' % PORT) # 循环接受客户端请求 while True: conn, addr = sock.accept() print('Connected by', addr) handle_request(conn) ``` 需要注意的是,这只是一个简单的示例代码,实际使用中需要考虑更多的安全性、可靠性和性能方面的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值