下面是数据传输的重点-CDataSocket类,函数不多,都比较重要。

  1、OnAccept  数据tcp服务器被连接的虚函数,由框架调用。

 void CDataSocket::OnAccept(int nErrorCode)
{
// Accept the connection using a temp CSocket object.
CAsyncSocket tmpSocket;
Accept(tmpSocket); SOCKET socket = tmpSocket.Detach();
Close(); Attach(socket); m_bConnected = TRUE; CAsyncSocket::OnAccept(nErrorCode);
}

  第7行 得到套接字描述符socket。第8行关闭监听的这个套接字,第11行关联socket与本对象,第12行,标记连接标志。这种处理方法少写一个类。因为tcp监听得一个socket,而连接上来的客户端也需要一个socket来与之通信。这样做适合只有一个客户端的情况。

  2、OnReceive  数据接收处理函数

 int CDataSocket::Receive()
{
TRACE("OnReceive\n");
int nRead = ; if (m_pControlSocket->m_nStatus == STATUS_UPLOAD)
{
if (m_File.m_hFile == NULL)
return ; byte data[PACKET_SIZE];
nRead = CAsyncSocket::Receive(data, PACKET_SIZE); switch(nRead)
{
case :
{
m_File.Close();
m_File.m_hFile = NULL;
Close();
// tell the client the transfer is complete.
m_pControlSocket->SendResponse("226 Transfer complete");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, , );
break;
}
case SOCKET_ERROR:
{
if (GetLastError() != WSAEWOULDBLOCK)
{
m_File.Close();
m_File.m_hFile = NULL;
Close();
m_pControlSocket->SendResponse("426 Connection closed; transfer aborted.");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, , );
}
break;
}
default:
{
TRY
{
m_File.Write(data, nRead);
}
CATCH_ALL(e)
{
m_File.Close();
m_File.m_hFile = NULL;
Close();
m_pControlSocket->SendResponse("450 Can't access file.");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, , );
return ;
}
END_CATCH_ALL;
break;
}
}
}
return nRead;
}

  如果处于上传状态,那么将接收到的数据写入文件。

  3、PreSendFile 与发送文件有关的函数

 BOOL CDataSocket::PrepareSendFile(LPCTSTR lpszFilename)
{
// close file if it's already open
if (m_File.m_hFile != NULL)
{
m_File.Close();
} // open source file
if (!m_File.Open(lpszFilename, CFile::modeRead | CFile::typeBinary))
{
return FALSE;
}
m_nTotalBytesSend = m_File.GetLength(); if (m_pControlSocket->m_dwRestartOffset < m_nTotalBytesSend)
{
m_nTotalBytesTransfered = m_pControlSocket->m_dwRestartOffset;
}
else
{
m_nTotalBytesTransfered = ;
}
return TRUE;
}

 初始化文件描述符m_File,m_nTotalBytesSend,m_nTotalBytesTransfered。

 4、 SendFile函数  调用PrepareSendFile,调用OnSend发送文件。

 void CDataSocket::SendFile(LPCTSTR lpszFilename)
{
if (!PrepareSendFile(lpszFilename))
{
// change status
m_pControlSocket->m_nStatus = STATUS_IDLE; m_pControlSocket->SendResponse("426 Connection closed; transfer aborted."); // destroy this socket
AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, , );
return;
}
OnSend();
}

 5、SendData 发送数据 是为了LIST命令而准备,发送文件目录列表。

 6、OnSend 主要区分了list命令的情况和download的情况。

 void CDataSocket::OnSend(int nErrorCode)
{
CAsyncSocket::OnSend(nErrorCode);
switch(m_pControlSocket->m_nStatus)
{
case STATUS_LIST:
{
while (m_nTotalBytesTransfered < m_nTotalBytesSend)
{
DWORD dwRead;
int dwBytes; CString strDataBlock; dwRead = m_strData.GetLength(); if (dwRead <= PACKET_SIZE)
{
strDataBlock = m_strData;
}
else
{
strDataBlock = m_strData.Left(PACKET_SIZE);
dwRead = strDataBlock.GetLength();
} if ((dwBytes = Send(strDataBlock, dwRead)) == SOCKET_ERROR)
{
if (GetLastError() == WSAEWOULDBLOCK)
{
Sleep();
return;
}
else
{
TCHAR szError[];
wsprintf(szError, "Server Socket failed to send: %d", GetLastError()); // close the data connection.
Close(); m_nTotalBytesSend = ;
m_nTotalBytesTransfered = ; // change status
m_pControlSocket->m_nStatus = STATUS_IDLE; m_pControlSocket->SendResponse("426 Connection closed; transfer aborted."); // destroy this socket
AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, , );
}
}
else
{
m_nTotalBytesTransfered += dwBytes;
m_strData = m_strData.Mid(dwBytes);
}
}
if (m_nTotalBytesTransfered == m_nTotalBytesSend)
{
// close the data connection.
Close(); m_nTotalBytesSend = ;
m_nTotalBytesTransfered = ; // change status
m_pControlSocket->m_nStatus = STATUS_IDLE; // tell the client the transfer is complete.
m_pControlSocket->SendResponse("226 Transfer complete");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, , );
}
break;
}
case STATUS_DOWNLOAD:
{
while (m_nTotalBytesTransfered < m_nTotalBytesSend)
{
// allocate space to store data
byte data[PACKET_SIZE]; m_File.Seek(m_nTotalBytesTransfered, CFile::begin); DWORD dwRead = m_File.Read(data, PACKET_SIZE); int dwBytes; if ((dwBytes = Send(data, dwRead)) == SOCKET_ERROR)
{
if (GetLastError() == WSAEWOULDBLOCK)
{
Sleep();
break;
}
else
{
TCHAR szError[];
wsprintf(szError, "Server Socket failed to send: %d", GetLastError()); // close file.
m_File.Close();
m_File.m_hFile = NULL; // close the data connection.
Close(); m_nTotalBytesSend = ;
m_nTotalBytesTransfered = ; // change status
m_pControlSocket->m_nStatus = STATUS_IDLE; m_pControlSocket->SendResponse("426 Connection closed; transfer aborted."); // destroy this socket
AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, , );
}
}
else
{
m_nTotalBytesTransfered += dwBytes;
}
}
if (m_nTotalBytesTransfered == m_nTotalBytesSend)
{
// close file.
m_File.Close();
m_File.m_hFile = NULL; // close the data connection.
Close(); m_nTotalBytesSend = ;
m_nTotalBytesTransfered = ; // change status
m_pControlSocket->m_nStatus = STATUS_IDLE; // tell the client the transfer is complete.
m_pControlSocket->SendResponse("226 Transfer complete");
// destroy this socket
AfxGetThread()->PostThreadMessage(WM_DESTROYDATACONNECTION, , );
}
break;
}
}
}

  7、OnConnect函数  tcp连接成功时被框架调用的虚函数。

  8、OnClose函数 当数据发送完成或者接收完成后被框架调用的虚函数。主要做清理工作。

  9、

 

VC FTP服务器程序分析(四)的更多相关文章

  1. VC FTP服务器程序分析(一)

    想在QT上移植一个FTP服务器程序,先学习windows下的FTP服务器例子,然后随便动手写点东西. 在pudn上搜索 "FTP服务器端和客户端实现 VC“这几个关键字,就可以搜到下面要分析 ...

  2. VC FTP服务器程序分析(二)

    上面讲到了CClientThread类,打开这个类的实现,这个类实现了4个函数.依次分析: 1.InitInstance   其说明如下:InitInstance必须被重载以初始化每个用户界面线程的新 ...

  3. VC FTP服务器程序分析(三)

    CControlSocket类的分析,CControlSocket类的内容比较多,为什么呢.因为通信控制命令的传输全部在这里,通信协议的多样也导致了协议解析的多样. 1.OnReceive  其大致说 ...

  4. 搭建ftp服务器实现文件共享

    FTP服务器(File Transfer Protocol Server)是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务. FTP(File Transfer Protocol ...

  5. 转:【专题十二】实现一个简单的FTP服务器

    引言: 休息一个国庆节后好久没有更新文章了,主要是刚开始休息完心态还没有调整过来的, 现在差不多进入状态了, 所以继续和大家分享下网络编程的知识,在本专题中将和大家分享如何自己实现一个简单的FTP服务 ...

  6. Linux中搭建FTP服务器

    FTP工作原理 (1)FTP使用端口 [root@localhost ~]# cat /etc/services | grep ftp ftp-data 20/tcp #数据链路:端口20 ftp 2 ...

  7. 专题十二:实现一个简单的FTP服务器

    引言: 在本专题中将和大家分享如何自己实现一个简单的FTP服务器.在我们平时的上网过程中,一般都是使用FTP的客户端来对商家提供的服务器进行访问(上传.下载文件),例如我们经常用到微软的SkyDriv ...

  8. centos yum安装与配置vsFTPd FTP服务器(转)

    vsftpd作为FTP服务器,在Linux系统中是非常常用的.下面我们介绍如何在centos系统上安装vsftp. 什么是vsftpd vsftpd是一款在Linux发行版中最受推崇的FTP服务器程序 ...

  9. [CentOs7]搭建ftp服务器

    摘要 vsftpd 是“very secure FTP daemon”的缩写,安全性是它的一个最大的特点.vsftpd 是一个 UNIX 类操作系统上运行的服务器的名字,它可以运行在诸如 Linux. ...

随机推荐

  1. BZOJ 3850: ZCC Loves Codefires【贪心】

    Though ZCC has many Fans, ZCC himself is a crazy Fan of a coder, called "Memset137". It wa ...

  2. K-lord #3 (组合数学)

    题目描述 如图,设一个圆分成 n 个扇形 S1 ... ,Sn (扇形大小不一样),现用 k 种不同的颜色对这 n 个扇形进行染色 ( n>=3 , k>=3 ); 每一个扇形染一种颜色, ...

  3. ElasticSearch API 之 UPDATE

    ES本身是一个倾向于查询检索的框架,对于更新的操作,太过频繁总归不好的. 阅读本篇后,你可以使用Script对所有的文档执行更新操作,也可以使用doc对部分文档执行更新,也可以使用upsert对不存在 ...

  4. win8激活工具,win 8激活工具,windows8激活工具,赶紧来下载咯

    同事前几天买了一个电脑,装的win8的系统,由于装office,需要激活,找了下office的激活工具,那个Office激活工具自带有win8激活,同事点错了,把正版系统给激活了,变成盗版了(悲剧.. ...

  5. Bayan 2015 Contest Warm Up D. CGCDSSQ (math,pair,map,暴力)

    哎,只能转题解了,,, 8165031                 2014-10-10 15:53:42     njczy2010     D - CGCDSSQ             GN ...

  6. hdu 4885 (n^2*log(n)判断三点共线建图)+最短路

    题意:车从起点出发,每次只能行驶L长度,必需加油到满,每次只能去加油站或目的地方向,路过加油站就必需进去加油,问最小要路过几次加油站. 开始时候直接建图,在范围内就有边1.跑最短了,再读题后发现,若几 ...

  7. JS标签获取另一个页面传过来的href值

    a href=b.html?id=楼主>B页面</a>b.html中的获取函数:function getParam(){C1=window.location.href.split(& ...

  8. 《Java虚拟机原理图解》1.4 class文件中的字段表集合--field字段在class文件中是怎样组织的

    0.前言 了解JVM虚拟机原理是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述 ...

  9. Java屏幕截图工具 捕获屏幕

    原文:http://www.open-open.com/code/view/1420037709781 import java.awt.BorderLayout; import java.awt.Co ...

  10. git-flow 工作流 备忘清单

    关于 git-flow 是一个 git 扩展集,按 Vincent Driessen 的分支模型提供高层次的库操作. 查看详情 ★ ★ ★ 这个备忘清单展示了 git-flow 的基本操作和效果. ★ ...