跨平台文件传输工具
2016-02-15 15:13
411 查看
最近用到freebsd10.2,然而倒腾图形界面始终没有成功,各种代码无法拷贝到bsd上去,不可能用vi或者ee重复再敲一遍。
vmtools似乎也没法安装,于是就用ee敲了个最简单的bsd上的服务端,接收文件并保存到本地。精简版代码如下:
可以先在windows上编译出完整版作为一个客户端来连接bsd上的精简版,然后将完整版作为文件传输到bsd,再在bsd上编译出完整版,就可以实现双向文件拷贝了。
完整版可以在windows/linux/bsd上编译,linux上需要指定-std=c++11 windows上最好是vs2013及以后版本,完整版如下:
vmtools似乎也没法安装,于是就用ee敲了个最简单的bsd上的服务端,接收文件并保存到本地。精简版代码如下:
#include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <fstream> #include <string> struct FileCopyInfo { char fileName[128]; char fileLength; unsigned reserved; }; int main(int argc, char **argv) { auto serv = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(argv[1]); bind(serv, (sockaddr*)&addr, sizeof(sockaddr)); listen(serv, 5); while (true) { sockaddr_in client_addr; socklen_t length = sizeof(client_addr); auto con = accept(serv, (struct sockaddr*)&client_addr, &length); FileCopyInfo cpyInfo; recv(con, (char*)&cpyInfo, sizeof(cpyInfo), 0); char buf[1024]; std::ofstream ofs(argv[2], std::ios::binary | std::ios::out); int s = 0; do { s = recv(con, buf, 1024, 0); ofs.write(buf, s); } while (s>0); } return 0; }
可以先在windows上编译出完整版作为一个客户端来连接bsd上的精简版,然后将完整版作为文件传输到bsd,再在bsd上编译出完整版,就可以实现双向文件拷贝了。
完整版可以在windows/linux/bsd上编译,linux上需要指定-std=c++11 windows上最好是vs2013及以后版本,完整版如下:
#ifdef WIN32 #include <WinSock2.h> #include <WS2tcpip.h> #pragma comment(lib, "ws2_32.lib") #else #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> // g++ this.cpp -std=c++11 -lpthread -o test #endif #include <string.h> #include <iostream> #include <fstream> #include <thread> #include <string> #include <sstream> #include <algorithm> struct SocketTool { SocketTool() { #ifdef WIN32 WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2, 2); WSAStartup(wVersionRequested, &wsaData); #endif } template <typename SOCKET_TYPE> static int CloseSocket(SOCKET_TYPE skt) { #ifdef WIN32 return closesocket(skt); #else return close(skt); #endif } static sockaddr_in GenInAddr(const char *szIP, unsigned uPort) { sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(uPort); #ifdef WIN32 inet_pton(AF_INET, szIP, &addr.sin_addr); #else inet_aton(szIP, &addr.sin_addr); #endif return addr; } static std::string PrintInAddr(const sockaddr_in& addr) { char buf[128] = { 0 }; inet_ntop(AF_INET, (void*)&addr.sin_addr, buf, sizeof(buf)); auto port = ntohs(addr.sin_port); std::stringstream ss; ss << buf << ":" << port; return ss.str(); } ~SocketTool() { #ifdef WIN32 WSACleanup(); #endif } }; struct FileCopyInfo { char fileName[128]; unsigned fileLength; unsigned reserved; }; #ifdef WIN32 #include <WinSock2.h> #else #include <arpa/inet.h> #endif void N2L(FileCopyInfo& cpyInfo) { cpyInfo.fileLength = ntohl(cpyInfo.fileLength); } void L2N(FileCopyInfo& cpyInfo) { cpyInfo.fileLength = htonl(cpyInfo.fileLength); } template <typename SocketType> bool SendData(SocketType s, const char* buf, unsigned bufLen) { unsigned rest = bufLen; unsigned sended = 0; while (rest > 0) { auto r = send(s, buf + sended, rest, 0); if (r <= 0) { std::cout << "send failed" << std::endl; return false; } else { sended += r; rest -= r; } } return true; } bool SendFile(const char *pLocalFile, const char *ip, int port) { std::ifstream ifs(pLocalFile, std::ios::in | std::ios::binary); if (!ifs.is_open()) { std::cout << "open loacal file failed!" << std::endl; return false; } SocketTool sktInit; auto s = socket(AF_INET, SOCK_STREAM, 0); auto addr = SocketTool::GenInAddr(ip, port); auto ret = connect(s, (sockaddr*)&addr, sizeof(addr)); if (ret != 0) { std::stringstream ss; ss << "connect " << ip << ":" << port << "failed" << std::endl; std::cout << ss.str() << std::endl; } FileCopyInfo cpyInfo; const char* pSrcName = strrchr(pLocalFile, '/'); if (pSrcName == nullptr) { pSrcName = pLocalFile; } else { ++pSrcName; } strcpy(cpyInfo.fileName, pSrcName); ifs.seekg(0, std::ios::end); auto fileLen = ifs.tellg(); ifs.seekg(0, std::ios::beg); std::cout << "Sending " << fileLen << " bytes..."; unsigned uSended = 0; cpyInfo.fileLength = fileLen; L2N(cpyInfo); if (SendData(s, (const char*)&cpyInfo, sizeof(cpyInfo))) { char buf[1024] = { 0 }; do { ifs.read(buf, sizeof(buf)); auto l = ifs.gcount(); if (SendData(s, buf, l)) { uSended += l; } else { break; } } while (!ifs.eof()); } std::cout << uSended << "/" << fileLen << " bytes sended!" << std::endl; SocketTool::CloseSocket(s); return uSended == fileLen; } template <typename SocketType> bool RecvData(SocketType s, char* buf, unsigned bufLen) { unsigned recved = 0; auto rest = bufLen; while (rest > 0) { auto r = recv(s, buf + recved, rest, 0); if (r <= 0) { std::cout << "recv failed" << std::endl; return false; } else { recved += r; rest -= r; } } return true; } bool RecvFile(const char *pLocalDir, int port) { SocketTool sktTool; auto serv = socket(AF_INET, SOCK_STREAM, 0); int reuse = 1; if (setsockopt(serv, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) { std::cout << "setsockopt SO_REUSEADDR failed" << std::endl; return false; } auto addr = SocketTool::GenInAddr("0.0.0.0", port); if (bind(serv, (sockaddr*)&addr, sizeof(sockaddr)) == -1) { std::cout << "bind failed" << std::endl; return false; } if (listen(serv, 5) == -1) { std::cout << "listen failed" << std::endl; return false; } while (true) { sockaddr_in client_addr; socklen_t length = sizeof(client_addr); auto con = accept(serv, (struct sockaddr*)&client_addr, &length); if (con < 0) { std::cout << "accept failed!\n" << std::endl; } else { auto strClient = SocketTool::PrintInAddr(client_addr); std::string strLocalDir(pLocalDir); if (strLocalDir.back() != '/') { strLocalDir += "/"; } FileCopyInfo cpyInfo; if (RecvData(con, (char*)&cpyInfo, sizeof(cpyInfo))) { N2L(cpyInfo); std::cout << "Reading " << cpyInfo.fileName << " (" << cpyInfo.fileLength << "bytes) from " << strClient << "..." << std::endl; std::ofstream ofs(strLocalDir + cpyInfo.fileName, std::ios::out | std::ios::binary); if (ofs.is_open()) { char buf[1024] = { 0 }; unsigned uRest = cpyInfo.fileLength; while (uRest > 0) { auto uRead = uRest; if (uRead > sizeof(buf)) { uRead = sizeof(buf); } if (RecvData(con, buf, uRead)) { ofs.write(buf, uRead); uRest -= uRead; } else { break; } } std::cout << "recv finished: " << cpyInfo.fileLength - uRest << "/" << cpyInfo.fileLength << std::endl; } else { std::cout << "create file failed!" << std::endl; } } } SocketTool::CloseSocket(con); } SocketTool::CloseSocket(serv); } int main(int argc, char **argv) { if (argc == 4) { char *ip = argv[1]; int port = atoi(argv[2]); char *localFile = argv[3]; SendFile(localFile, ip, port); } else if (argc == 3) { int port = atoi(argv[1]); char *localDir = argv[2]; RecvFile(localDir, port); } else { std::cout << "usage: \n\tFileCpy remoteip remoteport localfile\n\tFileCpy localport localdir" << std::endl; return 0; } return 0; }
相关文章推荐
- Extension Xcode.IDEKit.CmdHandler.DebugSessionStressTest class 'DBGDebugMenuController' not found 解决
- Debug C++
- fedora安装sublime text教程
- 过年回来,发现证书无效
- 学习android app笔记
- Beanstalkd中文协议解读
- HTML5开发移动web应用——SAP UI5篇(5)
- NopCommerce基本性能压力测试
- JSON.parse()和JSON.stringify()
- Android短信窃听器
- Android的eclipse插件adt无法启动“No target available”
- 打包生成IPA包时遇到错误:missing ios distribution signing identity for XXXXXXXXXX
- 【Python】linux安装tornado
- [Python]网络爬虫4
- hbase java api 使用demo
- [设计报告]有屏的地方就有Bad Apple!! —— 12864版
- 一些VR延迟优化方法
- c语言的const的写法
- Android开发之如何保证Service不被杀掉(broadcast+system/app)
- 【题解】Healthy Holsteins