论坛首页 编程语言技术论坛

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

浏览 6165 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-04-11  
C++
花了将近两天分析了一个1500行的FTP代码,又查阅了RFC文挡等。学习了很多东西。
组长突然通知不用FTP了, 
这里把FTP大概的一个SOCKET方式整理一下,以备以后学习使用
总的来说流程就是:
FTP分两个TCP连接,一个是控制流,一个是数据流
命令流比如是登陆啊,帮助,退出啊之类的
数据流进行数据的传输,使用的是另外的端口,如果不指定,默认用21。具体可查看RFC文档

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

#include <iostream>
#include <winsock2.h>

#pragma comment(lib, "Ws2_32")

using namespace std;

int main(int argc, char **argv)
{
	char session_tmp[1024];
	int timeout = 10;
	unsigned short port = 21;
	char *ip = "192.168.0.238";

	struct sockaddr_in addr_client;
	SOCKET socket_fd;

	int err;
	WSADATA wsaData;
	err = WSAStartup(0x0202, &wsaData );
	if ( err != 0 ) 
	{
		{
			cout<<"[-] WSAStartup"<<endl;
		}                                 
	}


	if( (socket_fd = socket(AF_INET,SOCK_STREAM,0)) == -1)
	{
		cout<<"[-] socket"<<endl;
		return -1;
	}
	setsockopt(socket_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int));
	setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int));

	addr_client.sin_family=AF_INET;
	addr_client.sin_port = htons(port);
	addr_client.sin_addr.S_un.S_addr = inet_addr(ip);

	if( connect(socket_fd, (struct sockaddr*)&addr_client, sizeof(sockaddr)) ==-1 )
	{
		cout<<"[-] connect"<<endl;
		return -1;
	}

	int data_len;

	data_len = recv(socket_fd, session_tmp, 1024, 0);

	if( SOCKET_ERROR==data_len )
	{
		cout<<"[-] recv"<<GetLastError()<<endl;
		return -1;
	}
	session_tmp[data_len] = '\0';
	cout<<session_tmp<<endl;
	
	char name[10];
	char passwd[10];
	cout<<"name:";
	scanf("%s", name);
	cout<<endl;

	//
	_snprintf(session_tmp, sizeof(session_tmp), "USER %s\r\n",
			  name);
	data_len=send(socket_fd, session_tmp, strlen(session_tmp), 0);
	data_len=recv(socket_fd, session_tmp, 1024, 0);
	
	session_tmp[data_len]='\0';
	cout<<endl;
	cout<<session_tmp<<endl;
	//end 

	//
	cout<<"passwd:";
	scanf("%s", passwd);

	_snprintf(session_tmp, sizeof(session_tmp), "PASS %s\r\n",
			  passwd);

	data_len=send(socket_fd, session_tmp, strlen(session_tmp), 0);
	data_len=recv(socket_fd, session_tmp, 1024, 0);

	session_tmp[data_len]='\0';
	cout<<endl;
	cout<<session_tmp<<endl;
	//end 

	//ls port,client listen on a port and wait the server to connect.
	//组织好IP地址和端口号
	//用port的话,发送port命令
	//用ls查看,发送ls命令
	//accept服务器连接
	//recv。接受服务器传来的消息

	WSACleanup();


	return 0;	
}
   发表时间:2008-04-11  
代码只是走一个流程。。
0 请登录后投票
   发表时间:2008-04-12  

session_tmp[data_len]='\0';  
请教下,这句有什么意义吗?
0 请登录后投票
   发表时间:2008-04-12  
回复 AppZ
_snprintf()
函数是这样的:如果拷贝的东西超过他,那么末尾就不加'\0'
虽然说在接收服务器发送的消息,一般不会超过1024,而且也会自动加。但为了安全起见,还是手工加了个’\0‘。即在接受长度的基础上
0 请登录后投票
   发表时间:2008-04-14  
这是java代码?
0 请登录后投票
   发表时间:2008-04-15  
没说这是JAVA啊。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics