在这个程序中,客户端读取桌面的一个 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"<