/**
* 函数:XSendData
* 描述:发送数据
* 参数:sock socket
* lpszBuff 缓冲区
* nDataSize 数据长度
* nPacketSize 每次传输的数据块长度
* nOverTime 超时 (秒)
* 返回:实际传输的数据长度
*/
int XSendData(SOCKET sock, LPSTR lpszBuff, int nDataSize, int nPacketSize, int nOverTime)
{
int nSent = 0; // 已发送的长度
int nSending; // 即将发送的长度
int nRet; // 每次发送的实际长度
int nErrNo;
DWORD dwStart = GetTickCount();
while(1)
{
nSending = nDataSize - nSent;
if (nSending <= 0)
{
break;
}
else if (nSending > nPacketSize)
{
nSending = nPacketSize;
}
// 判断是否超时
if((int)(GetTickCount() - dwStart) > 1000 * nOverTime)
{
OutputDebugString(_T("SendData OverTime."));
break;
}
nRet = send(sock, lpszBuff + nSent, nSending, 0);
if (nRet == SOCKET_ERROR)
{
nRet = 0;
nErrNo = WSAGetLastError();
TCHAR szErr[128];
_stprintf(szErr, _T("SendData Socket Error : %d"), nErrNo);
OutputDebugString(szErr);
break;
}
nSent += nRet;
}
return nSent;
}
/**
* 函数:XRecvData
* 描述:接收数据
* 参数:sock socket
* lpszBuff 缓冲区
* nDataSize 数据长度
* nPacketSize 每次传输的数据块长度
* nOverTime 超时 (秒)
* 返回:实际传输的数据长度
*/
int XRecvData(SOCKET sock, LPSTR lpszBuff, int nDataSize, int nPacketSize, int nOverTime)
{
int nRecved = 0; // 已接收的长度
int nRecving; // 即将接收的长度
int nRet; // 每次接收的实际长度
int nErrNo;
DWORD dwStart = GetTickCount();
while(1)
{
nRecving = nDataSize - nRecved;
if (nRecving <= 0)
{
break;
}
else if (nRecving > nPacketSize)
{
nRecving = nPacketSize;
}
// 判断是否超时
if((int)(GetTickCount() - dwStart) > 1000 * nOverTime)
{
OutputDebugString(_T("RecvData OverTime."));
break;
}
nRet = recv(sock, lpszBuff + nRecved, nRecving, 0);
if (nRet == SOCKET_ERROR)
{
nRet = 0;
nErrNo = WSAGetLastError();
TCHAR szErr[128];
_stprintf(szErr, _T("RecvData Socket Error : %d"), nErrNo);
OutputDebugString(szErr);
break;
}
nRecved += nRet;
}
return nRecved;
}
/**
* 函数:XSendFile
* 描述:发送文件
* 参数:sock socket
* lpszFile 文件路径
* dwFileSize 文件长度
* nBuffSize 缓冲区长度
* 返回:文件长度
*/
int XSendFile(SOCKET sock, LPCTSTR lpszFile, DWORD dwFileSize, int nBuffSize)
{
// 准备本地文件句柄
CFile file;
if (!file.Open(lpszFile, CFile::modeRead))
{
XOutputDebugString(_T("XSendFile打开文件%s失败."), lpszFile);
return -1;
}
// 读取文件内容并发送数据
DWORD dwSent = 0;
int nSending, nRet;
char *lpszSend = new char[nBuffSize];
if (lpszSend == NULL)
{
XOutputDebugString(_T("XSendFile 分配制堆内存失败."));
file.Close();
return -1;
}
while (dwSent < dwFileSize)
{
nSending = dwFileSize - dwSent;
if (nSending <= 0)
{
break;
}
else if (nSending > nBuffSize)
{
nSending = nBuffSize;
}
memset(lpszSend, 0x00, nBuffSize);
file.Read(lpszSend, nSending);
nRet = XSendData(sock, lpszSend, nSending, 1024, 1);
if (nRet == nSending)
{
dwSent += nRet;
file.Seek(dwSent, CFile::begin);
}
else
{
break;
}
}
// 关闭文件句柄
file.Close();
delete[] lpszSend;
return dwSent;
}
/**
* 函数:XRecvFile
* 描述:接收文件
* 参数:sock socket
* lpszFile 文件路径
* dwFileSize 文件长度
* nBuffSize 缓冲区大小
* 返回:文件长度
*/
int XRecvFile(SOCKET sock, LPCTSTR lpszFile, DWORD dwFileSize, int nBuffSize)
{
// 准备本地文件句柄
CFile file;
if (!file.Open(lpszFile, CFile::modeCreate|CFile::modeWrite))
{
XOutputDebugString(_T("XRecvFile打开文件%s失败."), lpszFile);
return -1;
}
// 下载数据并写入到文件中
DWORD dwRecvd = 0;
int nRecving, nRet;
char *lpszRecv = new char[nBuffSize];
if (lpszRecv == NULL)
{
XOutputDebugString(_T("XRecvFile 分配制堆内存失败."));
file.Close();
return -1;
}
while (dwRecvd < dwFileSize)
{
nRecving = dwFileSize - dwRecvd;
if (nRecving <= 0)
{
break;
}
else if (nRecving > nBuffSize)
{
nRecving = nBuffSize;
}
memset(lpszRecv, 0x00, nBuffSize);
nRet = XRecvData(sock, lpszRecv, nRecving, 1024, 30);
if (nRet == nRecving)
{
file.Write(lpszRecv, nRet);
file.SeekToEnd();
dwRecvd += nRet;
}
else
{
break;
}
}
// 关闭文件句柄
file.Close();
delete[] lpszRecv;
return dwRecvd;
}