[请教]:TCP/IP 在进行大文件传输的时候出现的问题!
我写了一个TCP/IP 的程序,进行文件的传输,如果文件不大,传输基本没问题,但是文件只要稍微大一点的话传输就会出现问题。
还望大神给指点指点。如下是我的代码,全部拷贝过去创建两个项目就可以编译执行测试:
文件夹的布局:
根目录:TCP 文件夹
根目录下三个文件夹:TCP/include/(服务器客户端共用头文件) TCP/Client/(客户端源代码) TCP/Server/(服务器源代码)
// TCP/include/ShareHeadFile.h
#ifndef SHARE_HEAD_FILE_H
#define SHARE_HEAD_FILE_H
#define PORT(8888)
#define BUFF_SIZE(4000)
// 在网络上传输结构体,指定结构体的字节对齐
#pragma pack(4)
struct STRU_Package
{
unsigned long ulByteAmount;// 当前发送文件总字节数
unsigned long ulIndex;// 当前是第几个包,从0 开始递加
unsigned long ulByteCount;// 当前包中包含的字节数
char arrBuffer[BUFF_SIZE];// 当前包中的数据字段
};
#pragma pack()
#endif // SHARE_HEAD_FILE_H
// TCP/Server/ServerMain.cpp
#include
#pragma comment(lib, "WS2_32.LIB")
int main(int argc, char *argv[])
{
BeginServer();
return 0;
}
// TCP/Server/Server.h
#ifndef SERVER_H
#define SERVER_H
int BeginServer();
#endif // SERVER_H
// TCP/Server/Server.cpp
#include
#include
#include
#include
#include
#include
#pragma comment(lib, "WS2_32.LIB")
static DWORD __stdcall ThreadFunc(LPVOID lpParam);
int BeginServer()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0)
{
printf("初始化WSADATA 失败!\n");
return 0;
}
// 1. 创建SOCKET
SOCKET sockServer = socket(AF_INET, SOCK_STREAM, 0);
if (sockServer == SOCKET_ERROR)
{
printf("创建SOCKET 失败!\n");
WSACleanup();
return 0;
}
// 2. 绑定服务器主机地址
sockaddr_in addrServer;
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(PORT);
addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
// 绑定
if (bind(sockServer, (sockaddr *)&addrServer, sizeof(addrServer)) == SOCKET_ERROR)
{
printf("绑定失败!\n");
closesocket(sockServer);
WSACleanup();
return 0;
}
// 3. 监听
listen(sockServer, 10);
// 4. 连接通信
while (1)
{
sockaddr_in addrClient;
int nLen = sizeof(addrClient);
SOCKET sockClient = accept(sockServer, (sockaddr *)&addrClient, &nLen);
if (sockClient == SOCKET_ERROR)
{
printf("accept 失败!\n");
break;
}
printf("客户端: %s 连接上来!\n", inet_ntoa(addrClient.sin_addr));
CreateThread(NULL, 0, &ThreadFunc, &sockClient, 0, NULL);
}
closesocket(sockServer);
WSACleanup();
return 0;
}
static DWORD __stdcall ThreadFunc(LPVOID lpParam)
{
if (lpParam == NULL)
return 0;
SOCKET sockClient = *((SOCKET *)lpParam);
char strFile[4096] = {0};
recv(sockClient, strFile, 4096, 0);
std::ifstream readFile(strFile, std::ios::binary);
if (!readFile)
{
printf("打开文件: %s 失败!\n", strFile);
closesocket(sockClient);
return 0;
}
STRU_Package struBuffer;
// 求出文件大小
readFile.seekg(0, std::ios_base::end);
struBuffer.ulByteAmount =(unsigned long)readFile.tellg();
unsigned long ulPackageCount = struBuffer.ulByteAmount / BUFF_SIZE;
if (struBuffer.ulByteAmount % BUFF_SIZE != 0)
++ulPackageCount;
printf("发送包总个数: %d\n", ulPackageCount);
ulPackageCount = htonl(ulPackageCount);
int nResult = send(sockClient, (const char *)&ulPackageCount, sizeof(ulPackageCount), 0);
struBuffer.ulByteAmount = htonl(struBuffer.ulByteAmount);
readFile.seekg(0, std::ios_base::beg);
Sleep(3000);
unsigned long ulIndex = 0;
unsigned long ulSize = 0;
while (1)
{
struBuffer.ulIndex = htonl(ulIndex++);
if (readFile.eof())
break;
readFile.read(struBuffer.arrBuffer, BUFF_SIZE);
ulSize = (unsigned long)readFile.gcount();
struBuffer.ulByteCount = htonl(ulSize);
printf("发送第 %7u个包。\n", ulIndex);
printf("发送数据大小:%7u BYTE.\n", ulSize);
nResult = send(sockClient, (const char *)&struBuffer, sizeof(struBuffer), 0);
if (nResult
{
printf("发送失败...\n");
break;
}
}
printf("文件全部发送完毕。\n");
readFile.close();
closesocket(sockClient);