win2win(windows之间局域网文件传输)
简介
这是一个基于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: seafly0616@qq.com\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

浙公网安备 33010602011771号