使用SOCKET实现FTP的简易客户端

2015-01-17 20:00:57|?次阅读|上传:wustguangh【已有?条评论】发表评论

关键词:C/C++, 网络通信|来源:唯设编程网

3.  与FTP服务器建立连接

int CFTP::ftp_connect(int timeout) 
{ 
	m_sockctrl = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 

	//设置超时	
	if (setsockopt(m_sockctrl,SOL_SOCKET,SO_RCVTIMEO, 
		(const char*) &timeout,sizeof(timeout)) == -1) 
	{ 
		perror("setsockopt"); 
		closesocket(m_sockctrl); 
		return -1; 
	} 	

	if(0==m_sockctrl)
		return -1; 
	struct sockaddr_in addr; 
	addr.sin_family = AF_INET; 
	addr.sin_port = htons(21); 
	addr.sin_addr.s_addr = inet_addr(m_ip); 
	int err = connect(m_sockctrl,(sockaddr*)&addr,sizeof(addr)); 
	if(err)
		return -1; 
	//220 Microsoft FTP Service
	err = recv_buf(m_resp,sizeof(m_resp)); 
	if(err || get_state_code(m_resp) != 220)
		return -1;
	
	return 0; 
}

参数timeout用来设置SOCKET的超时时间,单位为毫秒,SOCKET的创建使用socket函数完成,该函数有三个参数,函数的具体解释可以参考:C/C++编程之socket基本函数的用法。SOCKET的参数设置使用setsockopt,如果出错该函数返回-1。通过socket函数创建SOCKET以后,就可以使用connect函数建立与服务器的连接。同样,该函数的用法可以参考:C/C++编程之socket基本函数的用法。连接成功以后,FTP服务器会返回对应的提示信息,我们调用函数recv_buf接收服务器的返回内容,get_state_code函数可以从服务器的返回内容提取对应的返回码。

4. 接收FTP服务器的返回内容

//接收FTP服务器的返回内容
int CFTP::recv_buf(char* recv_buf,int buf_length) 
{ 
	memset(recv_buf,'',buf_length);
	int len = recv(m_sockctrl,recv_buf,buf_length,0); 	
	if(-1 == len){		
		return  WSAGetLastError();
	}
	//接收残余数据
	char tmp[1024] = {0};

	while(len != SOCKET_ERROR && len != 0){
		len = recv(m_sockctrl,tmp,sizeof(tmp),0);
		if(len != SOCKET_ERROR && len != 0){
			strcat(recv_buf,tmp);
			memset(tmp,0,sizeof(tmp));
		}
	}
	//应该保存ftp运行日志
	save_log(recv_buf, m_pLogFile);
	return 0; 
}

这个函数有连个参数,第一个参数是用来存储返回内容的缓存区(本例我们使用一个char数组),第二个参数指定了缓存区的长度(也就是char数组的长度)。首先使用memset清空缓存区的内容,由于很多字符串处理函数都是以‘’作为字符串的结束字符,所以我们将缓存区的所有数据重置为''。接收服务器的返回内容我们使用recv函数,该函数的返回值是接收到的数据长度,该函数的详细用法可以参考:C/C++编程之socket基本函数的用法

5. 从字符串获取返回码

//得到状态码
int CFTP::get_state_code( const char* p_buf )
{
	int res_code = -1;
	if(p_buf[0]>'9'||p_buf[0]<'0')
		return res_code;

	//分离出字符串
	std::string s(p_buf);	
	std::istringstream ss(s);  //拷贝构造输出串流
	ss>>res_code;  //输入到t
	return res_code;
}

这个函数的目的是从服务器返回的字符串中提取开头的返回码,使用了字符串流简化我们的程序。

发表评论0条 】
网友评论(共?条评论)..
使用SOCKET实现FTP的简易客户端