局域网内文件传输的windows程序实现

该博客介绍了如何在Windows环境下,利用VS创建窗体项目,结合Winsock和文件读写功能,实现局域网内的文件接收和发送程序。通过理解原理、查看程序结构,读者可以下载代码进行学习。
摘要由CSDN通过智能技术生成

原理

  • 使用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)//去掉文件路径后的文件长度需要大于0
		return -1;
	j = ++start;	//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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值