首页 > 系统相关 >win2win(windows之间局域网文件传输)

win2win(windows之间局域网文件传输)

时间:2023-11-22 10:04:40浏览次数:29  
标签:return socket windows 文件传输 length printf recvData win2win sin

简介

  这是一个基于C语言编写的控制台程序,可以在VS平台下编译。

使用场景

  由于Windows之间自带的文件共享太费事,步骤太繁琐,于是参考网络文章Ctrl+C了一个凑出了一个小工具,主要实现网线直连或者同网段的局域网内的两台Windows电脑之间的文件传输。程序基于TCP协议传输,因此在运行程序之前,确保两台电脑正确配置了IP地址,并且保证IP地址在同一网段即可。出版本单线程,传输中小文件还是够用的,后续有空会更新出多线程并发以提高传输效率。

使用方法

 

完整源代码(win2win.c):下面是完整的源代码(单文件),直接新建一个 Visual Studio C++ 的控制台应用程序工程,然后把内容贴进去编译即可。

#include<stdio.h>
#include<Winsock2.h>
#include<time.h>
#include<string.h>
#include <stdint.h>
#pragma warning(disable:4996)
#pragma comment(lib,"ws2_32.lib")

// Server fixed to be recv people
// Client fixed to be send people

#define USER_ERROR -1
#define MAX_PACKET_SIZE 2048

long getFileSize(const char *FileName)
{
	FILE *fp = fopen(FileName, "rb");
	if (fp == NULL)
		return 0;

	fseek(fp, 0, SEEK_END);
	long fsize = ftell(fp);
	fclose(fp);

	return fsize;
}

void printProcess(double cur, double total)
{
	long percent = cur / total * 100;
	printf("Finished %%%d\r", percent);
	fflush(stdout);
}

long str2num(const char *str)
{
	char *endptr;
	return strtol(str, &endptr, 0);
}

int main_server(uint16_t bindPort)
{
	char recvData[MAX_PACKET_SIZE];
	int ret;
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		printf("Failed to load Winsock.\n");
		return USER_ERROR;
	}

	SOCKET socket_of_server;
	SOCKET socket_of_client;
	socket_of_server = socket(AF_INET, SOCK_STREAM, 0);
	if (socket_of_server == INVALID_SOCKET)
	{
		printf("socket() Failed:%d\n", WSAGetLastError());
		return USER_ERROR;
	}

	struct sockaddr_in s_sin;
	s_sin.sin_family = AF_INET;
	s_sin.sin_port = htons(bindPort);
	s_sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	if (bind(socket_of_server, (LPSOCKADDR)&s_sin, sizeof(s_sin)) == SOCKET_ERROR)
	{
		printf("blind() Failed:%d\n", WSAGetLastError());
		return USER_ERROR;
	}
	if (listen(socket_of_server, 5) == SOCKET_ERROR)
	{
		printf("listen() Failed:%d\n", WSAGetLastError());
		return USER_ERROR;
	}
	struct sockaddr_in c_sin;
	int c_sin_len = sizeof(c_sin);

	int loopflag = 1;
	while (loopflag)
	{
		printf("Waiting for Connection ...\n");
		socket_of_client = accept(socket_of_server, (SOCKADDR *)&c_sin, &c_sin_len);
		if (socket_of_client == INVALID_SOCKET)
			printf("accept() Failed:%d\n", WSAGetLastError());
		else
		{
			printf("Get New Connection IP: %s\r\n", inet_ntoa(c_sin.sin_addr));

			memset(recvData, 0, sizeof(recvData));
			ret = recv(socket_of_client, recvData, sizeof(recvData), 0);
			printf("Get File Name: %s\n", recvData);

			FILE *fp = fopen(recvData, "wb+");
			if (fp == NULL)
			{
				fprintf(stderr, "fopen() %s failed, %s\n", recvData, strerror(errno));
				return -1;
			}

			memset(recvData, 0, sizeof(recvData));
			ret = recv(socket_of_client, recvData, sizeof(recvData), 0);
			long fsize = ntohl(*((long *)recvData));
			printf("Get File Size: %ld\n", fsize);
			printf("Get File Content ...\n");

			long length = 0;
			long curoff = 0;
			long remain = fsize;
			while (1)
			{
				length = recv(socket_of_client, recvData, sizeof(recvData), 0);
				if (length > 0)
				{
					//printf("Get length is %ld\n", length);
					fwrite(recvData, 1, length, fp);
					curoff += length;
					remain -= length;
					printProcess((double)curoff, fsize);
				}

				if (remain <= 0)
				{
					break;
				}
			}

			printf("\nGet File Complete!\n");
			loopflag = 0;
			fclose(fp);
		}
	}

	closesocket(socket_of_server);
	WSACleanup();
	return 0;
}



int main_client(const char *FileName, const char *toIP, uint16_t toPort)
{
	char sendData[MAX_PACKET_SIZE];
	int ret;


	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		printf("WSAStartup() failed.\n");
		return USER_ERROR;
	}

	SOCKET socket_client = socket(AF_INET, SOCK_STREAM, 0);
	if (socket_client == INVALID_SOCKET)
	{
		printf(" Failed socket() \n");
		return 0;
	}

	struct sockaddr_in server_in;
	server_in.sin_family = AF_INET;
	server_in.sin_port = htons(toPort);
	server_in.sin_addr.S_un.S_addr = inet_addr(toIP);

	if (connect(socket_client, (struct sockaddr*)&server_in, sizeof(server_in)) == -1)
	{
		printf(" Failed connect() \n");
		return 0;
	}
	else
	{
		printf("Connecting to IP:%s, Port:%d\n", inet_ntoa(server_in.sin_addr), server_in.sin_port);

		memset(sendData, 0, sizeof(sendData));
		strcpy(sendData, FileName);
		send(socket_client, sendData, sizeof(sendData), 0);
		printf("Put File Name: %s\n", FileName);

		memset(sendData, 0, sizeof(sendData));
		long fsize = getFileSize(FileName);
		*((long *)sendData) = htonl(fsize);
		send(socket_client, sendData, sizeof(sendData), 0);
		printf("Put File Size: %ld\n", fsize);
		printf("Put File Content ...\n");

		if (fsize <= 0)
		{
			goto end_connect;
		}

		Sleep(1000);//1000ms

		FILE *fp = fopen(FileName, "rb");
		if (fp == NULL)
		{
			fprintf(stderr, "fopen() %s failed, %s\n", FileName, strerror(errno));
			exit(1);
		}

		long remain = fsize;
		long length = 0;
		long curoff = 0;
		while (1)
		{
			memset(sendData, 0, sizeof(sendData));
			length = fread(sendData, 1, sizeof(sendData), fp);
			if (length > 0)
			{
				//printf("Put length is %ld\n", length);
				send(socket_client, sendData, sizeof(sendData), 0);
				curoff += length;
				remain -= length;
				printProcess((double)curoff, fsize);
			}
			else
			{
				break;
			}
		}
		printf("\nPut File Complete!\n");
		fclose(fp);
	}

end_connect:
	closesocket(socket_client);
	WSACleanup();
	return 0;
}

void cmd_help(const char *exe)
{
	fprintf(stderr, "Usage: %s  <R|T>  [FileName] [IP] [Port]\n", exe);
	fprintf(stderr, "  e.g: %s   R  6666                        --Rx From Port 6666\n", exe);
	fprintf(stderr, "  e.g: %s   T  hello.txt  127.0.0.1  6666  --Tx To Port 6666\n", exe);
	fprintf(stderr, " Note:\n");
	fprintf(stderr, "       T    --Tx File\n");
	fprintf(stderr, "       R    --Rx File\n");
	fprintf(stderr, "        \n");
	fprintf(stderr, "Author: [email protected]\n");
	fprintf(stderr, "Reference link: https://blog.csdn.net/sinat_37372543/article/details/87989599\n");
}

int main(int argc, const char *argv[])
{
	if (argc < 2)
	{
		cmd_help(argv[0]);
		return -1;
	}

	const char *optstr = argv[1];

	switch (*optstr)
	{
	case 'T':
	{
		if (argc != 5)
		{
			cmd_help(argv[0]);
			return -1;
		}
		const char *FileName = argv[2];
		const char *toIP = argv[3];
		uint16_t toPort = str2num(argv[4]);
		main_client(FileName, toIP, toPort);
		break;
	}
	case 'R':
	{
		if (argc != 3)
		{
			cmd_help(argv[0]);
			return -1;
		}
		uint16_t bindPort = str2num(argv[2]);
		main_server(bindPort);
		break;
	}
	default:
	{
		fprintf(stderr, "Error: Invalid option '%c' \n", *optstr);
		cmd_help(argv[0]);
		break;
	}

	}

	return 0;
}
//原文链接:https ://blog.csdn.net/sinat_37372543/article/details/87989599

  

 

标签:return,socket,windows,文件传输,length,printf,recvData,win2win,sin
From: https://www.cnblogs.com/seafly0616/p/17848219.html

相关文章

  • windows 搭建 swoole开发环境
    1.下载:swoole官网下载swoole-cli-v5.0.3-cygwin-x64.zip只支持64位的系统 2.解压到指定文件夹:C:\phpstudy_pro\swoole-cli-v5.0.3-cygwin-x64 3.设置环境变量:把解压后的文件夹下的bin目录路径配置到系统的Path环境变量中,确定保存 4.检查安装情况:打开命令行输入:s......
  • change windows cmd prompt 修改windows命令行提示符
    通过修改环境变量控制cmd提示符。 refcmd-HowdoIchangethecommand-linepromptinWindows?-StackOverflowhttps://stackoverflow.com/questions/12028372/how-do-i-change-the-command-line-prompt-in-windowsAbetterPROMPTforCMD.EXEorCoolPromptEnv......
  • 七天.NET 8操作SQLite入门到实战 - 第二天 在 Windows 上配置 SQLite环境
    前言SQLite的一个重要的特性是零配置的、无需服务器,这意味着不需要复杂的安装或管理。它跟微软的Access差不多,只是一个.db格式的文件。但是与Access不同的是,它不需要安装任何软件,非常轻巧。七天.NET8操作SQLite入门到实战详细教程第一天SQLite简介EasySQLite项目源码地址......
  • 5.2 Windows驱动开发:内核取KERNEL模块基址
    模块是程序加载时被动态装载的,模块在装载后其存在于内存中同样存在一个内存基址,当我们需要操作这个模块时,通常第一步就是要得到该模块的内存基址,模块分为用户模块和内核模块,这里的用户模块指的是应用层进程运行后加载的模块,内核模块指的是内核中特定模块地址,本篇文章将实现一个获......
  • 5.3 Windows驱动开发:内核取应用层模块基址
    在上一篇文章《内核取ntoskrnl模块基地址》中我们通过调用内核API函数获取到了内核进程ntoskrnl.exe的基址,当在某些场景中,我们不仅需要得到内核的基地址,也需要得到特定进程内某个模块的基地址,显然上篇文章中的方法是做不到的,本篇文章将实现内核层读取32位应用层中特定进程模块基址......
  • 5.4 Windows驱动开发:内核通过PEB取进程参数
    PEB结构(ProcessEnvirormentBlockStructure)其中文名是进程环境块信息,进程环境块内部包含了进程运行的详细参数信息,每一个进程在运行后都会存在一个特有的PEB结构,通过附加进程并遍历这段结构即可得到非常多的有用信息。在应用层下,如果想要得到PEB的基地址只需要取fs:[0x30]即......
  • 8.3 Windows驱动开发:内核遍历文件或目录
    在笔者前一篇文章《内核文件读写系列函数》简单的介绍了内核中如何对文件进行基本的读写操作,本章我们将实现内核下遍历文件或目录这一功能,该功能的实现需要依赖于ZwQueryDirectoryFile这个内核API函数来实现,该函数可返回给定文件句柄指定的目录中文件的各种信息,此类信息会保存在PF......
  • 7.1 Windows驱动开发:内核监控进程与线程回调
    在前面的文章中LyShark一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以监控进程线程创建为例,在Win10系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原理是创建一个回调事件,当有进程或线程被创建或者注销时,系统会通过回......
  • Windows CMD常用命令大全
    1.常用命令1.1cd命令//进入d盘D://进入F盘F:cd/?//获取使用帮助cd\//跳转到硬盘的根目录cdC:\WINDOWS//跳转到当前硬盘的其他文件d://跳转到其他硬盘cd/de:\software//跳转到其他硬盘的其他文件夹,注意此处必须加/d参数。否......
  • 8.2 Windows驱动开发:内核解锁与强删文件
    在某些时候我们的系统中会出现一些无法被正常删除的文件,如果想要强制删除则需要在驱动层面对其进行解锁后才可删掉,而所谓的解锁其实就是释放掉文件描述符(句柄表)占用,文件解锁的核心原理是通过调用ObSetHandleAttributes函数将特定句柄设置为可关闭状态,然后在调用ZwClose将其文件关......