原理
- 使用VS创建windows窗体项目
- Winsock + 文件读写实现文件接收程序fileReceiver.exe和发送程序fileSender.exe
程序
下载链接
代码
#include <iostream>
#include <fstream>
#include "winsock.h"
#define SLICE_SIZE 1280
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int getFileName(const char* src, char* dest)
{
int start, end, i(0), j;
for (end = 0; end < SLICE_SIZE && src[end] != '\0'; end++);
for (start = end; start > 0 && src[start] != '\\'; start--);
if (end == SLICE_SIZE || end - start < 2)
return -1;
j = ++start;
while(j < end)
dest[i++] = src[j++];
return (end - start);
}
int main()
{
cout << "============SENDER===========\n" \
<< "| file transfer demo v1.\n" \
<< "| this program is a file sender.\n" \
<< "| start receiving...\n" \
<< "=============================\n";
WSADATA wsaData;
SOCKADDR_IN ServerAddr;
SOCKET NewConnection;
int Port = 58585;
string serverIP;
cout << "please input server IP: ";
cin >> serverIP;
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = inet_addr(serverIP.c_str());
WSAStartup(MAKEWORD(2, 2), &wsaData);
NewConnection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (connect(NewConnection, (SOCKADDR*)& ServerAddr, sizeof(SOCKADDR)) < 0) {
cout << "connect to server " << inet_ntoa(ServerAddr.sin_addr) << "...\n";
}
else {
cout << "connect to server success.\n";
while (1) {
cout << "please input file path: \n";
string filename;
cin >> filename;
ifstream file(filename, ios_base::binary);
char* buf = new char[SLICE_SIZE];
file.seekg(0, ios_base::end);
long long filesize(file.tellg());
int sendsize(SLICE_SIZE), filenamesize;
file.seekg(0, ios_base::beg);
cout << "filesize: " << filesize << endl;
filenamesize = getFileName(filename.c_str(), buf);
if (filenamesize == -1){
cout << "get file name error\n";
delete buf;
continue;
}
sendsize = send(NewConnection, buf, filenamesize, 0);
if (sendsize != filenamesize)
{
cout << "send file name error\n";
delete buf;
continue;
}
buf[0] = (filesize >> 32) & 0xFF;
buf[1] = (filesize >> 24) & 0xFF;
buf[2] = (filesize >> 16) & 0xFF;
buf[3] = (filesize >> 8) & 0xFF;
buf[4] = filesize & 0xFF;
sendsize = send(NewConnection, buf, 5, 0);
if (sendsize != 5)
{
cout << "send file size error\n";
delete buf;
continue;
}
int download_percent = 0;
for (int readsize(0); readsize < filesize; readsize += sendsize) {
sendsize = (filesize - readsize) > SLICE_SIZE ? SLICE_SIZE : filesize - readsize;
file.read(buf, sendsize);
sendsize = send(NewConnection, buf, sendsize, 0);
if (sendsize < 1) {
cout << "file send error " << errno << endl;
break;
}
if ((float)download_percent < (float)readsize / filesize * 100)
{
download_percent++;
cout << "sending... " << download_percent << "%\n";
}
}
delete buf;
file.close();
cout << "file send complete.\n\n";
}
}
closesocket(NewConnection);
system("pause");
return 0;
}
#include <iostream>
#include <fstream>
#include "winsock.h"
#define SLICE_SIZE 1280
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int main()
{
system("ipconfig");
cout << "==========RECEIVER===========\n" \
<< "| file transfer demo v1.\n" \
<< "| this program is a file receiver.\n" \
<< "| start receiving...\n" \
<< "=============================\n";
WSADATA wsaData;
SOCKET ListeningSocket;
SOCKADDR_IN ServerAddr;
SOCKET NewConnection;
SOCKADDR_IN ClientAddr;
int Port = 58585;
WSAStartup(MAKEWORD(2, 2), &wsaData);
ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(ListeningSocket, (SOCKADDR*)& ServerAddr, sizeof(ServerAddr));
listen(ListeningSocket, 2);
int len = sizeof(ClientAddr);
long long filelen, recvlen(0);
char* buf = new char[1280];
cout << "awaiting request...\n";
NewConnection = accept(ListeningSocket, (SOCKADDR*)& ClientAddr, &len);
cout << "connect to " << inet_ntoa(ClientAddr.sin_addr) << " success.\n";
while (1) {
cout << "getting file name...\n";
len = recv(NewConnection, buf, SLICE_SIZE, 0);
if (len < 1) {
cout << "recv error. " << errno << endl;
closesocket(NewConnection);
break;
}
buf[len] = '\0';
cout << "filename: " << buf << endl;
ofstream file(buf, ios_base::binary);
if (file.fail()) {
cout << "create file failed.\n" << "program end.\n";
break;
}
len = recv(NewConnection, buf, 5, 0);
if (len != 5) {
cout << "recv file size error. " << errno << endl;
closesocket(NewConnection);
break;
}
filelen = ((long long)buf[0] << 32 & 0xFF00000000) | ((long long)buf[1] << 24 & 0xFF000000) | ((long long)buf[2] << 16 & 0xFF0000) | ((long long)buf[3] << 8 & 0xFF00) | ((long long)buf[4] & 0xFF);
cout << "filesize: " << filelen << endl;
len = recv(NewConnection, buf, SLICE_SIZE, 0);
while (len > 0) {
recvlen += len;
file.write(buf, len);
if (recvlen == filelen)
break;
len = recv(NewConnection, buf, SLICE_SIZE, 0);
}
file.close();
}
closesocket(NewConnection);
closesocket(ListeningSocket);
WSACleanup();
system("pause");
return 0;
}