您的位置:首页 > 其它

VC+CSocket文件传送示例

2012-02-16 14:10 155 查看
服务器端示例代码

#define PRE_AGREED_PORT 8686 //定义端口号
#define SEND_BUFFER_SIZE 4096 //buffer大小

BOOL CYourServerClass::SendFileToRemoteRecipient(CString fName)
{

AfxSocketInit(NULL);
CSocket sockSrvr;
sockSrvr.Create(PRE_AGREED_PORT);//创建一个Sokcet并监听
sockSrvr.Listen();//监听
CSocket sockConnection;
//用另一个Soket来收发数据
sockSrvr.Accept(sockConnection);
//接受从客户端发来的连接请求

BOOL bRet = TRUE;

int fileLength, cbLeftToSend;
BYTE* sendData = NULL;

CFile sourceFile;
CFileException fe;
BOOL bFileIsOpen = FALSE;

if( !( bFileIsOpen = sourceFile.Open( fName,
CFile::modeRead | CFile::typeBinary, &fe ) ) )
{
TCHAR strCause[256];
fe.GetErrorMessage( strCause, 255 );
TRACE( "SendFileToRemoteRecipient encountered
an error while opening the local file\n"
"\tFile name = %s\n\tCause = %s\n\tm_cause = %d\n\tm_IOsError = %d\n",
fe.m_strFileName, strCause, fe.m_cause, fe.m_lOsError );

//在这里处理错误

bRet = FALSE;
goto PreReturnCleanup;
}

//首先发送文件长度

fileLength = sourceFile.GetLength();
fileLength = htonl( fileLength );

cbLeftToSend = sizeof( fileLength );

do
{
int cbBytesSent;
BYTE* bp = (BYTE*)(&fileLength) + sizeof(fileLength) - cbLeftToSend;
cbBytesSent = sockConnection.Send( bp, cbLeftToSend );

// test for errors and get out if they occurred
if ( cbBytesSent == SOCKET_ERROR )
{
int iErr = ::GetLastError();
TRACE( "SendFileToRemoteRecipient returned a socket
error while sending file length\n"
"\tNumber of Bytes sent = %d\n"
"\tGetLastError = %d\n", cbBytesSent, iErr );

//在这里处理错误

bRet = FALSE;
goto PreReturnCleanup;
}

cbLeftToSend -= cbBytesSent;
}
while ( cbLeftToSend>0 );

//开始发送文件数据
sendData = new BYTE[SEND_BUFFER_SIZE];

cbLeftToSend = sourceFile.GetLength();

do
{

int sendThisTime, doneSoFar, buffOffset;

sendThisTime = sourceFile.Read( sendData, SEND_BUFFER_SIZE );
buffOffset = 0;

do
{
doneSoFar = sockConnection.Send( sendData + buffOffset,
sendThisTime );

//看执行是否成功
if ( doneSoFar == SOCKET_ERROR )
{
int iErr = ::GetLastError();
TRACE( "SendFileToRemoteRecipient returned a socket error
while sending chunked file data\n"
"\tNumber of Bytes sent = %d\n"
"\tGetLastError = %d\n", doneSoFar, iErr );

//处理错误

bRet = FALSE;
goto PreReturnCleanup;
}

buffOffset += doneSoFar;
sendThisTime -= doneSoFar;
cbLeftToSend -= doneSoFar;
}
while ( sendThisTime > 0 );

}
while ( cbLeftToSend > 0 );

PreReturnCleanup: // 出口点

delete[] sendData;

if ( bFileIsOpen )
sourceFile.Close();

sockConnection.Close();

return bRet;

}

客户端示例代码

#define PRE_AGREED_PORT 8686
#define RECV_BUFFER_SIZE 4096

BOOL CYourClientClass::GetFileFromRemoteSender(CString strIP,
CString fName)
{
AfxSocketInit(NULL);
CSocket sockClient;
sockClient.Create();
// PRE_AGREED_PORT 是 #define 8686
sockClient.Connect( strIP, PRE_AGREED_PORT );

//连接服务器

BOOL bRet = TRUE;

int dataLength, cbBytesRet, cbLeftToReceive;
BYTE* recdData = NULL;

CFile destFile;
CFileException fe;
BOOL bFileIsOpen = FALSE;

//打开或创建文件

if( !( bFileIsOpen = destFile.Open( fName, CFile::modeCreate |
CFile::modeWrite | CFile::typeBinary, &fe ) ) )
{
TCHAR strCause[256];
fe.GetErrorMessage( strCause, 255 );
TRACE( "GetFileFromRemoteSender encountered
an error while opening the local file\n"
"\tFile name = %s\n\tCause = %s\n\tm_cause = %d\n\tm_IOsError = %d\n",
fe.m_strFileName, strCause, fe.m_cause, fe.m_lOsError );

//在这里处理错误

bRet = FALSE;
goto PreReturnCleanup;
}

//得到文件的大小
cbLeftToReceive = sizeof( dataLength );

do
{
BYTE* bp = (BYTE*)(&dataLength) + sizeof(dataLength) - cbLeftToReceive;
cbBytesRet = sockClient.Receive( bp, cbLeftToReceive );

if ( cbBytesRet == SOCKET_ERROR || cbBytesRet == 0 )
{
int iErr = ::GetLastError();
TRACE( "GetFileFromRemoteSite returned
a socket error while getting file length\n"
"\tNumber of Bytes received (zero means connection was closed) = %d\n"
"\tGetLastError = %d\n", cbBytesRet, iErr );

//处理错误

bRet = FALSE;
goto PreReturnCleanup;
}

cbLeftToReceive -= cbBytesRet;

}
while ( cbLeftToReceive > 0 );

dataLength = ntohl( dataLength );

recdData = new byte[RECV_BUFFER_SIZE];
cbLeftToReceive = dataLength;

do
{
int iiGet, iiRecd;

iiGet = (cbLeftToReceive<RECV_BUFFER_SIZE) ?
cbLeftToReceive : RECV_BUFFER_SIZE ;
iiRecd = sockClient.Receive( recdData, iiGet );

if ( iiRecd == SOCKET_ERROR || iiRecd == 0 )
{
int iErr = ::GetLastError();
TRACE( "GetFileFromRemoteSite returned a socket error
while getting chunked file data\n"
"\tNumber of Bytes received (zero means connection was closed) = %d\n"
"\tGetLastError = %d\n", iiRecd, iErr );

//要在这里处理错误

bRet = FALSE;
goto PreReturnCleanup;
}

destFile.Write( recdData, iiRecd); // 写入数据
cbLeftToReceive -= iiRecd;

}
while ( cbLeftToReceive > 0 );

PreReturnCleanup: // 入口点

delete[] recdData;

if ( bFileIsOpen )
destFile.Close();

sockClient.Close();

return bRet;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: