最近在写一个文件传输工具,具体是将一个内网计算机上的文件读取到内存中,然后再发送到公网服务器,公网服务器收到后再转发到内网的另一台计算机,经过测试内网ReadFile一次最多读取8388608字节(8MB)的文件数据,公网最多接收到198667字节(194KB)的数据,下载速度最多300k/s,如何提高,下面是代码
内网
DWORD _stdcall fileUpThread(LPVOID lParam)
{
SOCKET sock = *(SOCKET*)lParam;
SendMsg sendMsg;
sendMsg.m_head.msg = { CMD_FILEUPSTART, NULL, NULL, NULL };
send(sock, (char*)&sendMsg, sizeof(SendMsg), NULL);
HANDLE hUpFile = INVALID_HANDLE_VALUE;
DWORD dwBytes;
double dbUpFileSize, dbTotalFileSize;
BYTE* sendBuffer = new BYTE[MAXBUFSIZE];
wcout.imbue(locale("chs"));
wcout << L"请输入文件路径:" << endl;
wcin >> sendMsg.m_head.file.cScrFile;
//获取上传文件
hUpFile = CreateFile(sendMsg.m_head.file.cScrFile, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
);
if (hUpFile == INVALID_HANDLE_VALUE)
dbUpFileSize = 0;
else
dbUpFileSize = GetFileSize(hUpFile, NULL);
sendMsg.m_head.file.iSize = dbUpFileSize;
dbTotalFileSize = dbUpFileSize;
//发送文件
if (send(sock, (char*)&sendMsg, sizeof(sendMsg), 0) <= 0 || dbUpFileSize <= 0)
{
shutdown(sock, 0x02);
closesocket(sock);
return 1;
}
int nRet = 0;
DWORD total = 0;
DWORD record = 0;
//循环发送文件数据
while (dbUpFileSize > 0)
{
if (!ReadFile(hUpFile, sendBuffer, MAXBUFSIZE, &dwBytes, NULL))
break;
nRet = send(sock, (char*)sendBuffer, dwBytes, 0);
if (nRet <= 0)
break;
dbUpFileSize -= nRet;
total = 100 - ((dbUpFileSize / dbTotalFileSize) * 100);
if (total != record)
{
if (0 == total % 10 && total != 0)
{
record = total;
cout << total << "%" << endl;
}
}
}
delete[] sendBuffer;
CloseHandle(hUpFile);
wcout << "文件上传完毕" << endl;
/*shutdown(sock, 0x2);
closesocket(sock);*/
}
内网
DWORD _stdcall fileDownThread(LPVOID lParam)
{
SOCKET sock = *(SOCKET*)lParam;
SendMsg sendMsg;
if (recv(sock, (char*)&sendMsg, sizeof(sendMsg), 0) <= 0)
{
shutdown(sock, 0x02);
closesocket(sock);
return 0;
}
HANDLE hDownFile = INVALID_HANDLE_VALUE;
double dbDownFileSize, dbTotalFileSize;
DWORD dwBufSize, dwBytes;
BYTE* recvBuffer=new BYTE[MAXBUFSIZE];
//为下载的数据创建文件
wchar_t filePath[260];
wcout.imbue(locale("chs"));
wcout << TEXT("请输入文件创建路径:") << endl;
wcin >> filePath;
hDownFile = CreateFile(filePath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hDownFile == INVALID_HANDLE_VALUE)
{
dbDownFileSize = 0;
PRINT(TEXT("文件下载-"), TEXT("创建文件失败"));
return 0;
}
else
{
dbDownFileSize = sendMsg.m_head.file.iSize;
PRINT(TEXT("文件下载-"), TEXT("创建文件成功"));
}
dbTotalFileSize = dbDownFileSize;
int nRet = 0;
DWORD total = 0;
DWORD record = 0;
//循环接收文件数据
while (1)
{
nRet = recv(sock, (char*)recvBuffer, MAXBUFSIZE, 0);
if (nRet <= 0)
break;
dbDownFileSize -= nRet;
total = 100 - ((dbDownFileSize / dbTotalFileSize) * 100);
if (total != record)
{
if (0 == total % 10 && total != 0)
{
record = total;
cout << total << "%" << endl;
}
}
WriteFile(hDownFile, recvBuffer, nRet, &dwBytes, NULL);
}
CloseHandle(hDownFile);
delete[] recvBuffer;
wcout.imbue(locale("chs"));
wcout << TEXT("文件下载完毕:") << endl;
//shutdown(sock, 0x02);
//closesocket(sock);
return 1;
}
公网数据转发
DWORD WINAPI TransmitData(LPVOID lParam)//在两个SOCKET中进行数据转发
{
SOCKINFO socks = *((SOCKINFO*)lParam);
SOCKET ClientSock = socks.ClientSock;
SOCKET ServerSock = socks.ServerSock;
char RecvBuf[MAXBUFSIZE] = { 0 };
fd_set Fd_Read;
int ret, nRecv;
while (1)
{
FD_ZERO(&Fd_Read);
FD_SET(ClientSock, &Fd_Read);
FD_SET(ServerSock, &Fd_Read);
ret = select(0, &Fd_Read, NULL, NULL, NULL);
if (ret <= 0)
goto error;
if (FD_ISSET(ClientSock, &Fd_Read))
{
nRecv = recv(ClientSock, RecvBuf, sizeof(RecvBuf), 0);
if (nRecv <= 0)
goto error;
ret = DataSend(ServerSock, RecvBuf, nRecv);
if (ret == 0 || ret != nRecv)
goto error;
}
if (FD_ISSET(ServerSock, &Fd_Read))
{
nRecv = recv(ServerSock, RecvBuf, sizeof(RecvBuf), 0);
if (nRecv <= 0)
goto error;
ret = DataSend(ClientSock, RecvBuf, nRecv);
if (ret == 0 || ret != nRecv)
goto error;
}
}
error:
closesocket(ClientSock);
closesocket(ServerSock);
return 0;
}