简介
这是一个基于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