|
发信人:sinister(sinister),信区:网络编程 标?题:传输大型文件实列 发信站:安全焦点(2001-06-15 18:51:45) 传输大型文件实列 SOCKET API,98/NT/2000调试通过。 C/S均建立读/写线程,一但连接,C/S便都可发送/接收文件,发送文件方式使 用字节流传送。将传送文件进行分割,每次传送1K,CLIENT或SERVER方收到后 进行重组。接收文件方式使用异步SOCKET,根据实际读入数据写文件。在LAN 上测试,C/S多次相互传输大型文件如:IIS,SQL SP,和几个上百M的文件, 效果良好。 Server.cpp //--------------------------------------------------------------------------- // SERVER端 // // 贾佳,jiasys@21cn.com //--------------------------------------------------------------------------- #include <vcl.h> #include <winsock.h> #define BUFFSIZE 1024 #pragma hdrstop #include "Server.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; WSADATA wsaData; SOCKET sck,sc; SOCKADDR_IN to,client; BOOL flag=TRUE; int iAddrSize,ret,ret_no,i=0; TCHAR szBuf[BUFFSIZE]; fd_set FdRead; //--------------------------------------------------------------------------- // ReadClient // // 接收文件数据线程,判断建立文件关键字,每次将实际读到的数据写入文件。 // //--------------------------------------------------------------------------- DWORD WINAPI ReadClient(LPVOID lPort) { HANDLE hFile=NULL; DWORD dwWrite,dwFileSize; TCHAR szFileName[MAX_PATH]; FD_ZERO(&FdRead); FD_SET(sck,&FdRead); while(TRUE) { ret_no=select(0,&FdRead,NULL,NULL,NULL); if(ret_no==SOCKET_ERROR) { closesocket(sck); return FALSE; } if(FD_ISSET(sck,&FdRead)) { iAddrSize=sizeof(client); sc=accept(sck,(SOCKADDR *)&client,&iAddrSize); if(sc==INVALID_SOCKET) { MessageBox(NULL,"accept error",NULL,MB_OK); closesocket(sc); WSACleanup(); } getpeername(sck,(SOCKADDR *)&client,&iAddrSize); ShowMessage(inet_ntoa(client.sin_addr)); FD_SET(sc,&FdRead); } if(FD_ISSET(sc,&FdRead)) { ZeroMemory(szBuf,sizeof(szBuf)); if((dwFileSize=recv(sc,szBuf,BUFFSIZE,0))==SOCKET_ERROR) { closesocket(sc); CloseHandle(hFile); return FALSE; } else if((strncmp(szBuf,"UPFILE_",lstrlen("UPFILE_")))==0) { wsprintf(szFileName,"c:\\%s",szBuf); hFile=CreateFile(szFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ, NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL| FILE_ATTRIBUTE_ARCHIVE,(HANDLE)NULL); if(hFile==INVALID_HANDLE_VALUE) { MessageBox(NULL,"Server Open File Error",NULL,MB_OK); return FALSE; } ZeroMemory(szBuf,sizeof(szBuf)); } else WriteFile(hFile,szBuf,dwFileSize,&dwWrite,NULL); } } CloseHandle(hFile); return TRUE; } //--------------------------------------------------------------------------- // WriteClient // // 发送文件数据线程,每次预读1K数据,根据实际读取发送,直到读取数据小于1K // //--------------------------------------------------------------------------- DWORD WINAPI WriteClient(LPVOID szFileName) { HANDLE hFile; DWORD dwRead,dwNdx; BOOL bRet; TCHAR szFileBuff[BUFFSIZE],szSend[MAX_PATH]; wsprintf(szSend,"DOWNFILE_%s",ExtractFileName((LPCTSTR)szFileName).c_str()); send(sc,szSend,lstrlen(szSend),0); hFile=CreateFile((LPCTSTR)szFileName,GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL| FILE_ATTRIBUTE_ARCHIVE,(HANDLE)NULL); if(hFile==INVALID_HANDLE_VALUE) { MessageBox(NULL,"Open File Error",NULL,MB_OK); ExitProcess(0); } do { bRet=ReadFile(hFile,szFileBuff,BUFFSIZE,&dwRead,NULL); if(bRet==FALSE) { MessageBox(NULL,"Read Buf ERROR!",NULL,MB_OK); break; } else if(dwRead==0) { MessageBox(NULL,"File EOF!",NULL,MB_OK); break; } else { send(sc,szFileBuff,dwRead,0); } }while(dwRead==BUFFSIZE); CloseHandle(hFile); return TRUE; } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { HANDLE hThread; DWORD dwTid; if(WSAStartup(MAKEWORD(1,1),&wsaData)!=NULL) { ShowMessage("初始化WINSOCK错误"); WSACleanup(); } if((sck=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR) { ShowMessage("SOCKET错误"); closesocket(sck); WSACleanup(); } to.sin_family=AF_INET; to.sin_port=htons(926); to.sin_addr.s_addr=htonl(INADDR_ANY); if(setsockopt(sck,SOL_SOCKET,SO_REUSEADDR,(LPSTR)&flag,sizeof(flag))==SOCKET_ERROR) { ShowMessage("setsockopt error!"); closesocket(sck); } if(bind(sck,(struct sockaddr *)&to,sizeof(to))==SOCKET_ERROR) { ShowMessage("Could not bind"); closesocket(sck); } else { listen(sck,1); hThread=CreateThread(NULL,0,ReadClient,(LPVOID)0,0,&dwTid); CloseHandle(hThread); } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { HANDLE hThread; DWORD dwTid; if(OpenDialog1->Execute()) { hThread=CreateThread(NULL,0,WriteClient,(LPVOID)OpenDialog1->FileName.c_str(),0,&dwTid); CloseHandle(hThread); } } //--------------------------------------------------------------------------- Client.cpp //--------------------------------------------------------------------------- // CLIENT端 // // 贾佳,jiasys@21cn.com //--------------------------------------------------------------------------- #include <vcl.h> #include <winsock.h> #define BUFFSIZE 1024 #pragma hdrstop #include "Client.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; WSADATA wsa; SOCKET sck; SOCKADDR_IN tto; hostent *host; fd_set FdRead; int port=926,ret,i; DWORD dwRead; //--------------------------------------------------------------------------- // ReadClient // // 接收文件数据线程,判断建立文件关键字,每次将实际读到的数据写入文件。 // //--------------------------------------------------------------------------- DWORD WINAPI ReadClient(LPVOID lParam) { HANDLE hFile; DWORD dwWrite,dwFileSize; TCHAR szFileName[MAX_PATH]; TCHAR szBuff[BUFFSIZE]; FD_ZERO(&FdRead); FD_SET(sck,&FdRead); while(TRUE) { ret=select(0,&FdRead,NULL,NULL,NULL); if(ret==SOCKET_ERROR) { closesocket(sck); return FALSE; } else if(FD_ISSET(sck,&FdRead)) { ZeroMemory(szBuff,sizeof(szBuff)); if((dwFileSize=recv(sck,szBuff,BUFFSIZE,0))==SOCKET_ERROR) { closesocket(sck); CloseHandle(hFile); return FALSE; } else if((strncmp(szBuff,"DOWNFILE_",lstrlen("DOWNFILE_")))==0) { wsprintf(szFileName,"c:\\%s",szBuff); hFile=CreateFile(szFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ, NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL| FILE_ATTRIBUTE_ARCHIVE,(HANDLE)NULL); if(hFile==INVALID_HANDLE_VALUE) { MessageBox(NULL,"Cli Open File Error",NULL,MB_OK); return FALSE; } ZeroMemory(szBuff,sizeof(szBuff)); } else WriteFile(hFile,szBuff,dwFileSize,&dwWrite,NULL); } } return TRUE; } //--------------------------------------------------------------------------- // WriteClient // // 发送文件数据线程,每次预读1K数据,根据实际读取发送,直到读取数据小于1K // //--------------------------------------------------------------------------- DWORD WINAPI WriteClient(LPVOID szFileName) { HANDLE hFile; DWORD dwRead,dwNdx; BOOL bRet; TCHAR szFileBuff[BUFFSIZE],szSend[MAX_PATH]; wsprintf(szSend,"UPFILE_%s",ExtractFileName((LPCTSTR)szFileName).c_str()); send(sck,szSend,lstrlen(szSend),0); hFile=CreateFile((LPCTSTR)szFileName,GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL| FILE_ATTRIBUTE_ARCHIVE,(HANDLE)NULL); if(hFile==INVALID_HANDLE_VALUE) { MessageBox(NULL,"Open File Error",NULL,MB_OK); ExitProcess(0); } do { bRet=ReadFile(hFile,szFileBuff,BUFFSIZE,&dwRead,NULL); if(bRet==FALSE) { MessageBox(NULL,"Read Buf ERROR!",NULL,MB_OK); break; } else if(dwRead==0) { MessageBox(NULL,"File EOF!",NULL,MB_OK); break; } else { send(sck,szFileBuff,dwRead,0); } }while(dwRead==BUFFSIZE); CloseHandle(hFile); return TRUE; } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { HANDLE hThread; DWORD dwTid; WSAStartup(MAKEWORD(1,1),&wsa); sck=socket(AF_INET,SOCK_STREAM,0); if(sck==INVALID_SOCKET) { ShowMessage("Could not create a sock"); ExitProcess(0); } else { host=gethostbyname(Edit1->Text.c_str()); tto.sin_family=AF_INET; tto.sin_port=htons(port); CopyMemory(&tto.sin_addr,host->h_addr,host->h_length); if((connect(sck,(struct sockaddr FAR *)&tto,sizeof(tto))==SOCKET_ERROR)) { ShowMessage("connect error!"); closesocket(sck); } else { hThread=CreateThread(NULL,0,ReadClient,(LPVOID)0,0,&dwTid); CloseHandle(hThread); } } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { HANDLE hThread; DWORD dwTid; if(OpenDialog1->Execute()) { hThread=CreateThread(NULL,0,WriteClient,(LPVOID)OpenDialog1->FileName.c_str(),0,&dwTid); CloseHandle(hThread); } } //---------------------------------------------------------------------------
|
|