用 VC+socket 传输大文件

在这个程序中,客户端读取桌面的一个 1.48 GB (1,597,701,030 字节) 的RAR文件发送给服务器。因为这里仅用于学习,所以客户端要连接的目标地址使用127.0.0.1。服务器端接将收的文件文件保存在C盘根目录下。

为保证程序的可靠发送,程序采用TCP协议。经过反复试验得出结论,程序中的重中之重是双方的 ReadFile 和 WriteFile。相反 recv 和 send 不是重要的。为了使代码尽量简化,程序去掉所有错误检查,只让服务器端的accept函数提示一下有人发起连接。双方收发完文件之后直接退出程序。

//服务器端

#include
#include
using namespace std;
const int iBufferSize = 1024*1024;
char buffer[iBufferSize];
void main()
{
	WSAData data;
	WSAStartup(MAKEWORD(2,2),&data);
	SOCKET s1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	SOCKADDR_IN addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	bind(s1, (SOCKADDR*)&addr, sizeof(addr));
	listen(s1, 5);
	int len = sizeof(addr);
	SOCKET s2 = accept(s1, (SOCKADDR*)&addr, & len);
	if(s2!=INVALID_SOCKET)
		cout<<" accept right"<0 )
	{
		ZeroMemory(buffer, iBufferSize);
		int size;
		size = recv(s2, buffer, iBufferSize, 0);

		DWORD dwNumBytes;
		while( TRUE )
		{
			if( i64FileSize.QuadPart < size )
				size = i64FileSize.QuadPart;
			WriteFile(hFile, buffer, size, &dwNumBytes, 0);
			i64FileSize.QuadPart -= dwNumBytes;
			if( dwNumBytes < size )
				size -= dwNumBytes;
			else
				break;
		}
	}
}


 

//客户端

#include
#include
using namespace std;

const int iBufferSize = 1024*1024;
char buffer[iBufferSize];

void main()
{
	WSAData data;
	WSAStartup(MAKEWORD(2,2),&data);
	SOCKET s1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	SOCKADDR_IN addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	connect(s1, (SOCKADDR*)&addr, sizeof(addr));

	HANDLE hFile = CreateFile(L"C:\\Users\\ys\\Desktop\\Visual C++开发入行真功夫光盘二次.rar",
		GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
	LARGE_INTEGER i64FileSize, i64FileSizeCopy;
	GetFileSizeEx(hFile, &i64FileSize);
	i64FileSizeCopy = i64FileSize;
	
	send(s1, (char*)&i64FileSize, sizeof(LARGE_INTEGER),0);

	while( i64FileSize.QuadPart > 0 )
	{
		DWORD dwNumBytes, dwNumberToRead = iBufferSize;
		while(TRUE)
		{
			if( i64FileSize.QuadPart <= dwNumberToRead )
				dwNumberToRead = i64FileSize.QuadPart;
			ReadFile(hFile, buffer, dwNumberToRead, &dwNumBytes, 0);
			i64FileSize.QuadPart -= dwNumBytes;
			if( dwNumBytes < dwNumberToRead )
				dwNumberToRead -= dwNumBytes;
			else
				break;
		}

		send(s1, buffer, iBufferSize, 0);

		cout<<"已发送 "
			<< (i64FileSizeCopy.QuadPart - i64FileSize.QuadPart)				<<"B "
			<< (i64FileSizeCopy.QuadPart - i64FileSize.QuadPart)/1024			<<"K "
			<< (i64FileSizeCopy.QuadPart - i64FileSize.QuadPart)/1024/1024		<<"M "
			<< (i64FileSizeCopy.QuadPart - i64FileSize.QuadPart)/1024/1024/1024 <<"G"<


 

你可能感兴趣的:(网络,VC/MFC)