基本信息
源码名称:c++ IPv6 文件传输实例源码下载
源码大小:13.20M
文件格式:.rar
开发语言:C/C++
更新时间:2017-04-05
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
#include "stdafx.h" #include "../Types.h"//必须放在首位 #include "FileTransfer.h" CString switchSize(ULONGLONG size) { CString str; ULONGLONG d = 1024; if (size < d) { str.Format(_T("%lld"),size); str = _T("Byte"); }else if (size < d *d ) { str.Format(_T("%.2lf"),(double)size/d); str = _T("KB"); }else if (size < d *d*d ) { str.Format(_T("%.2lf"),(double)size/(d*d)); str = _T("MB"); }else if (size < d *d*d*d ) { str.Format(_T("%.2lf"),(double)size/(d*d*d)); str = _T("GB"); }else { str.Format(_T("%.2lf"),(double)size/(d*d*d*d)); str = _T("TB"); } return str; } UINT WINAPI runProccess(LPVOID lpParam) { CFileTransfer* my = (CFileTransfer*)(lpParam); TRACE(_T("ID: %d start!\n"),my->getID()); if (my->ServerOrClient == ROLE_SERVER) { if (my->mAccept()==false) { TRACE(_T("ID: %d accept failed!\n"),my->getID()); return 0; } TRACE(_T("ID: %d accept success!\n"),my->getID()); }else { if (my->mConnect()==false) { TRACE(_T("ID: %d Connect failed!\n"),my->getID()); return 0; } TRACE(_T("ID: %d connect success!\n"),my->getID()); } if (my->isFolder) { my->dealFolder(); }else { if( my->dealFile()) { TRACE(_T("ID: %d TRUE\n"),my->getID()); }else { TRACE(_T("ID: %d FALSE\n"),my->getID()); } } TRACE(_T("ID: %d finished!\n"),my->getID()); return 1; } void CFileTransfer::setParam(CString Path,CString title,ULONGLONG fileSize, BOOL isFolder,SOCKADDR_IN PeerAddr4,SOCKADDR_IN6 PeerAddr6, int family,int RecvOrSend,int ServerOrClient,int id) { this->FilePath = Path; this->title = title; this->isFolder = isFolder; this->PeerAddr4 = PeerAddr4; this->PeerAddr4.sin_family = AF_INET; this->PeerAddr6 = PeerAddr6; this->family = family; this->RecvOrSend = RecvOrSend; this->ServerOrClient = ServerOrClient; this->speed = 0; this->TotalSize=fileSize; this->transferedSize =0; this->ID = id; this->bstop = FALSE; this->state = STATE_PENDING; this->m_socket = INVALID_SOCKET; this->hThread = NULL; TRACE(_T("creat one task.ID:%d\n"),this->ID); if (this->isFolder) { while (this->FilePath.GetAt(this->FilePath.GetLength()-1) == _T('\\')) { this->FilePath.Delete(this->FilePath.GetLength()-1); } } } int CFileTransfer::start(int port) { if (hThread) { TRACE(_T("ID:%d is already running.\n"),this->ID); return 0; } m_socket = socket(this->family,SOCK_STREAM,IPPROTO_TCP); if (m_socket == INVALID_SOCKET) { this->state=STATE_DEATH; return 0; } if (this->ServerOrClient == ROLE_SERVER) { int addrLen; if (this->family == AF_INET) { SOCKADDR_IN myaddr4; addrLen = sizeof(SOCKADDR_IN); myaddr4.sin_family = AF_INET; myaddr4.sin_port = 0; myaddr4.sin_addr.s_addr = INADDR_ANY; if(bind(m_socket,(SOCKADDR*)&myaddr4, addrLen) == SOCKET_ERROR|| getsockname(m_socket,(SOCKADDR*)&myaddr4,&addrLen) == SOCKET_ERROR) return 0; this->port = myaddr4.sin_port; }else { SOCKADDR_IN6 myaddr6; myaddr6.sin6_family = AF_INET6; myaddr6.sin6_port = 0; myaddr6.sin6_flowinfo = 0; myaddr6.sin6_addr = in6addr_any; myaddr6.sin6_scope_id = 0; addrLen = sizeof(SOCKADDR_IN6); if(bind(m_socket,(SOCKADDR*)&myaddr6, addrLen) == SOCKET_ERROR || getsockname(m_socket,(SOCKADDR*)&myaddr6,&addrLen) == SOCKET_ERROR) return 0; this->port = myaddr6.sin6_port; } //监听 if ( SOCKET_ERROR == listen(m_socket,SOMAXCONN)) { return 0; } }else { this->port = port; this->PeerAddr4.sin_family = AF_INET; this->PeerAddr4.sin_port = port; this->PeerAddr6.sin6_family = AF_INET6; this->PeerAddr6.sin6_flowinfo = 0; this->PeerAddr6.sin6_scope_id = 0; this->PeerAddr6.sin6_port = port; } hThread = (HANDLE)_beginthreadex(NULL,NULL,runProccess,this,0,NULL); if (NULL == hThread) { return 0; } return this->port; } BOOL CFileTransfer::mAccept() { int addrLen; this->state = STATE_CONNECT_RUNNING; SOCKET client_socket; if (this->family == AF_INET) { addrLen = sizeof(SOCKADDR_IN); client_socket = accept(m_socket,(SOCKADDR*)&(PeerAddr4),&addrLen); }else { addrLen = sizeof(SOCKADDR_IN6); client_socket = accept(m_socket,(SOCKADDR*)&(PeerAddr6),&addrLen); } closesocket(m_socket); m_socket = client_socket; //closesocket(client_socket); if(client_socket == INVALID_SOCKET ) { this->state = STATE_CONNECT_FAIL; return FALSE; } else { this->state = STATE_CONNECT_SUCCESS; return TRUE; } } BOOL CFileTransfer::mConnect() { this->state = STATE_CONNECT_RUNNING; int addrLen; if (this->family == AF_INET) { addrLen = sizeof(SOCKADDR_IN); if( connect(m_socket,(SOCKADDR*)&(PeerAddr4),addrLen) == SOCKET_ERROR) { this->state = STATE_CONNECT_FAIL; return FALSE; } }else { addrLen = sizeof(SOCKADDR_IN6); if( connect(m_socket,(SOCKADDR*)&(PeerAddr6),addrLen) == SOCKET_ERROR ) { this->state = STATE_CONNECT_FAIL; return FALSE; } } this->state = STATE_CONNECT_SUCCESS; return TRUE; } BOOL CFileTransfer::dealFolder() { this->state = STATE_RUNNING; if (this->RecvOrSend == FILE_RECVER) { if (recvFolder()) { this->state = STATE_FINISHED; return TRUE; }else { this->state = STATE_DEATH; return FALSE; } }else { if (sendFolder()) { this->state = STATE_FINISHED; return TRUE; }else { this->state = STATE_DEATH; return FALSE; } } if (this->bstop) { this->state = STATE_STOP; } } BOOL CFileTransfer::dealFile() { this->state = STATE_RUNNING; if (this->RecvOrSend == FILE_RECVER) { TRACE(_T("start recv!\n")); if (recvFile(this->FilePath,this->TotalSize)) { this->state = STATE_FINISHED; return TRUE; }else { this->state = STATE_DEATH; return FALSE; } }else { TRACE(_T("start send!\n")); if ( sendFile(this->FilePath) ) { this->state = STATE_FINISHED; return TRUE; }else { this->state = STATE_DEATH; return FALSE; } } if (this->bstop) { this->state = STATE_STOP; } } BOOL CFileTransfer::recvFolder() { TRACE(_T("start recv folder!\n")); FILENODE fileNode; CString path; while(TRUE) { //接收指令 ZeroMemory(&fileNode,sizeof(FILENODE)); TRACE(_T("recving next order!\n")); if(SOCKET_ERROR == recv(this->m_socket,(char*)&fileNode,sizeof(FILENODE),0)) { TRACE(_T("recv next order failed!\n")); return FALSE; } //结束指令 if (fileNode.order == 4)//over { TRACE(_T("recv finished order!\n")); break;; } path = this->FilePath _T("\\") fileNode.fileName; //目录名 if (fileNode.order == 3)//folder name { //创建目录 SHCreateDirectoryEx(NULL,path,NULL); TRACE(_T("recv folder name\n")); //发送ACK fileNode.order = 2; TRACE(_T("send ack: \n")); if (send(this->m_socket,(char*)&fileNode,sizeof(FILENODE),0)==SOCKET_ERROR) { TRACE(_T("send ack failed: %d\n"),GetLastError()); return FALSE; } }else//文件名 { //发送ACK TRACE(_T("recved file name: \n")); fileNode.order = 2; TRACE(_T("send ack: \n")); if (send(this->m_socket,(char*)&fileNode,sizeof(FILENODE),0)==SOCKET_ERROR) { TRACE(_T("send ack failed: %d\n"),GetLastError()); return FALSE; } //接收文件 TRACE(_T("recving file: \n")); if ( recvFile(path,fileNode.fileSize)==FALSE ) { TRACE(_T("recving file failed: %d\n "),GetLastError()); return FALSE; } TRACE(_T("recv file success: \n")); //发送ACK fileNode.order = 2; TRACE(_T("send ack: \n")); if (send(this->m_socket,(char*)&fileNode,sizeof(FILENODE),0)==SOCKET_ERROR) { TRACE(_T("send ack failed: %d\n"),GetLastError()); return FALSE; } } } TRACE(_T("finished recv folder!\n")); return TRUE; } BOOL CFileTransfer::sendFolder() { if (DFSFolder(this->FilePath)) { FILENODE fileNode; ZeroMemory(&fileNode,sizeof(FILENODE)); fileNode.order = 4; TRACE(_T("send over order\n")); if (send(this->m_socket,(char*)&fileNode,sizeof(FILENODE),0)==SOCKET_ERROR) { return FALSE; } return TRUE; } return FALSE; } BOOL CFileTransfer::DFSFolder(CString path) { CFileFind finder; BOOL bWorking = finder.FindFile(path _T("\\*.*")); ULONGLONG size = 0; FILENODE fileNode; if (bstop) { finder.Close(); return FALSE; } //发送文件夹路径 ZeroMemory(&fileNode,sizeof(FILENODE)); int index = path.Find(title); lstrcpy(fileNode.fileName,path.Mid(index).LockBuffer()); fileNode.order = 3; TRACE(_T("send folser name\n ")); if (send(this->m_socket,(char*)&fileNode,sizeof(FILENODE),0)==SOCKET_ERROR) { return FALSE; } //等待对方的ack ZeroMemory(&fileNode,sizeof(FILENODE)); TRACE(_T("recving ack: \n")); if(SOCKET_ERROR == recv(this->m_socket,(char*)&fileNode,sizeof(FILENODE),0)) { return FALSE; } if (fileNode.order != 2) { return FALSE; } TRACE(_T("recved ack: \n")); //收到ACK while (bWorking) { if (bstop) { finder.Close(); return FALSE; } bWorking = finder.FindNextFile(); if (finder.IsDots()|| finder.IsSystem()) continue; CString path = finder.GetFilePath(); if (finder.IsDirectory()) { TRACE(_T("dfs: \n")); if (DFSFolder(path) == FALSE) return FALSE; }else { //发送文件名 ZeroMemory(&fileNode,sizeof(FILENODE)); index = path.Find(title); lstrcpy(fileNode.fileName,path.Mid(index).LockBuffer()); fileNode.fileSize = finder.GetLength(); fileNode.order = 1; TRACE(_T("send file name: \n")); if (send(this->m_socket,(char*)&fileNode,sizeof(FILENODE),0)==SOCKET_ERROR) { TRACE(_T("send file name failed: %d\n"),GetLastError()); return FALSE; } //等待对方ACK ZeroMemory(&fileNode,sizeof(FILENODE)); if(SOCKET_ERROR == recv(this->m_socket,(char*)&fileNode,sizeof(FILENODE),0)) { return FALSE; } TRACE(_T("recved ack: \n")); //发送文件内容 TRACE(_T("sending file: \n")); if (fileNode.order == 2 && sendFile(path) == FALSE) { return FALSE; } TRACE(_T("send file success: \n")); //等待对方的ack ZeroMemory(&fileNode,sizeof(FILENODE)); TRACE(_T("recving ack: \n")); if(SOCKET_ERROR == recv(this->m_socket,(char*)&fileNode,sizeof(FILENODE),0)) { return FALSE; } if (fileNode.order != 2) { return FALSE; } TRACE(_T("recved ack: \n")); } } finder.Close(); return TRUE; } BOOL CFileTransfer::recvFile(CString path,ULONGLONG fileSize) { CFile file; CFileException ex; if (file.Open(path,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite|CFile::shareExclusive ,&ex)) { file.SetLength(fileSize); file.SeekToBegin(); this->state = STATE_RUNNING; DWORD time_s = GetTickCount(); DWORD time_e; ULONGLONG RecvSize = 0; ULONGLONG RecvSizeEX = this->transferedSize; ULONGLONG ret; TRACE(_T("Recving!\n")); //接收 while (RecvSize < fileSize) { if (bstop) { file.Close(); return FALSE; } ret = recv(this->m_socket,data,sizeof(data),0); if(ret == 0 || ret == SOCKET_ERROR || this->bstop) { file.Close(); return FALSE; } //this->transferedSize = ret; RecvSize = ret; this->transferedSize = ret; file.Write(data,ret);//写入文件 time_e = GetTickCount(); if(time_e - time_s >= 1000) { this->speed = (this->transferedSize - RecvSizeEX) / ( (time_e - time_s) / 1000); RecvSizeEX = this->transferedSize; time_s = time_e; } } file.Close(); return TRUE; } //TCHAR szError[1024]; //ex.GetErrorMessage(szError, 1024); file.Close(); return FALSE; } BOOL CFileTransfer::sendFile(CString path) { //初始化 CFile file(path,CFile::modeRead|CFile::shareDenyWrite); ULONGLONG fileSize = file.GetLength(); file.SeekToBegin();//文件指针 this->state = STATE_RUNNING;//线程状态 DWORD time_s = GetTickCount(); DWORD time_e; ULONGLONG sendSize = 0; ULONGLONG sendSizeEX = this->transferedSize; ULONGLONG ret,size,temp; TRACE(_T("Sending!\n")); //发送文件 while (sendSize < fileSize) { if (bstop) { file.Close(); return FALSE; } //读文件 ret = file.Read(data,DATABLOCK); if (ret < 0) { file.Close(); return FALSE; } size = 0; temp = 0; //发送 while (size < ret) { temp = send(this->m_socket,data size,ret-size,0); if (temp == SOCKET_ERROR || this->bstop) { file.Close(); return FALSE; } size = temp ; } //this->transferedSize = ret; sendSize = ret; this->transferedSize = ret; //计算传输速度 time_e = GetTickCount(); if(time_e - time_s >= 1000) { this->speed = (this->transferedSize - sendSizeEX) / ( (time_e - time_s) / 1000); sendSizeEX = this->transferedSize; time_s = time_e; } } file.Close(); return TRUE; } void CFileTransfer::setState(int state) { this->state = state; } int CFileTransfer::getState() { return this->state; } int CFileTransfer::getID() { return this->ID; } CString CFileTransfer::getSpeed() { return switchSize(this->speed) _T("/s"); } CString CFileTransfer::getPecent() { CString str; if (this->TotalSize == 0) { str = _T("100"); }else { str.Format(_T("%0.2f"),100.0* (double)this->transferedSize / (double)this->TotalSize); } str = _T("%"); return str; } CString CFileTransfer::getAlreadyCompelete() { return switchSize(this->transferedSize); } CString CFileTransfer::getSendOrRecver() { if (this->RecvOrSend == FILE_RECVER) { return _T("接收"); } return _T("发送"); } CString CFileTransfer::getTitle() { return this->title; } void CFileTransfer::deleteAll() { //_endthreadex(hThread); CloseHandle(hThread); closesocket(m_socket); } ULONGLONG CFileTransfer::getFolderSize(CString path) { CFileFind finder; BOOL bWorking = finder.FindFile(_T("*.*")); ULONGLONG size = 0; while (bWorking) { bWorking = finder.FindNextFile(); if (finder.IsDots()) continue; if (finder.IsDirectory()) { size = getFolderSize(finder.GetFilePath()); }else { size =finder.GetLength(); } } finder.Close(); return size; } void CFileTransfer::stop() { this->bstop = TRUE; WaitForSingleObject(hThread,INFINITE); }