server:
#include <Winsock2.h>
#pragma comment (lib,"ws2_32")
BYTE command[1024*2];
SOCKET sockSrv,sockConn;
SOCKADDR_IN addrSrv,addrClient;
int len=sizeof(SOCKADDR);
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
AfxMessageBox("加载套接字库失败!");
return;
}
sockSrv=socket(AF_INET,SOCK_STREAM,0);
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(5555);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5);
while(1){
sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
if(sockConn == INVALID_SOCKET){
continue;
}
memset((char*)&command,0,sizeof(command));
if(recv(sockConn,(char*)&command,sizeof(command),0)==SOCKET_ERROR){
break;
}else{
_SOCKET_STREAM_FILE_INFO* StreamFileInfo = (_SOCKET_STREAM_FILE_INFO*)command;
CFileDialog Dlg(0,0,StreamFileInfo->szFileTitle); //选择保存文件位置
if(Dlg.DoModal()!=IDOK) return;
long FileLen= 0;
FileLen = FileLen|(StreamFileInfo->nFileSizeHigh);
FileLen = FileLen << 32;
FileLen = FileLen|(StreamFileInfo->nFileSizeLow);
CFile file;
int nChunkCount=FileLen/(1024*1024);
if(nChunkCount==0){
nChunkCount++;
}else{
if(FileLen%nChunkCount!=0){
nChunkCount++;
}
}
if(file.Open(Dlg.GetPathName(),CFile::modeWrite|CFile::typeBinary|CFile::modeCreate)){
char *date = new char[1024*1024];
for(int i=0;i<nChunkCount;i++){
long nLeft;
if(i+1==nChunkCount) //最后一块
nLeft=FileLen-1024*1024*(nChunkCount-1);
else
nLeft=1024*1024;
long FileLength = nLeft;
int idx=0;
while(nLeft>0){
int ret=recv(sockConn,&date[idx],nLeft,0);
if(ret==SOCKET_ERROR){
AfxMessageBox("error");
return;
}
idx+=ret;
nLeft-=ret;
}
file.Write(date,FileLength);
}
file.Close();
delete[] date;
}
}
}
client:
#include <Winsock2.h>
#pragma comment (lib,"ws2_32")
BYTE command[1024*2];
SOCKET server;
SOCKADDR_IN serveraddr;
WORD ver=MAKEWORD(2,2);
WSADATA wsadata;
WSAStartup(ver,&wsadata);
server=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(5555);
serveraddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
if(connect(server,(SOCKADDR*)&serveraddr,sizeof(serveraddr))<0)
{
AfxMessageBox("连接失败!");
return ;
}
CFileDialog Dlg(TRUE);
if(Dlg.DoModal()!=IDOK) //选择文件对话框
return;
CFile myFile; //选择要传输的文件
if(!myFile.Open(Dlg.GetPathName(),CFile::modeRead|CFile::typeBinary))
{
AfxMessageBox("文件不存在!",MB_OK|MB_ICONERROR);
return;
}
SOCKET_STREAM_FILE_INFO StreamFileInfo; //文件结构类型对象
WIN32_FIND_DATA FindFileData;
HANDLE FindFileInfo;
if( (FindFileInfo = FindFirstFile(Dlg.GetPathName(),&FindFileData)) == INVALID_HANDLE_VALUE)
{
AfxMessageBox("error");
return;
}
FindClose(FindFileInfo);
memset(&StreamFileInfo,0,sizeof(SOCKET_STREAM_FILE_INFO));
strcpy(StreamFileInfo.szFileTitle,myFile.GetFileTitle());
//StreamFileInfo.szFileTitle = FindFileData.cFileName;
StreamFileInfo.dwFileAttributes = FindFileData.dwFileAttributes;
StreamFileInfo.ftCreationTime = FindFileData.ftCreationTime;
StreamFileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime;
StreamFileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime;
StreamFileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh;
//memcpy(StreamFileInfo,FindFileData,sizeof(WIN32_FIND_DATA));
StreamFileInfo.nFileSizeLow = FindFileData.nFileSizeLow;
//AfxMessageBox(Dlg.GetPathName());
long FileLen=0;
FileLen = FileLen|StreamFileInfo.nFileSizeHigh;
FileLen = FileLen << 32;
FileLen = FileLen|StreamFileInfo.nFileSizeLow;
memset((char*)&command,0,sizeof(command));
memcpy((char*)&command,&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO));
send(server,(char*)&command,sizeof(command),0);
myFile.Close();
//CFile myFile;
if(!myFile.Open(Dlg.GetPathName(),CFile::modeRead|CFile::typeBinary))
{
AfxMessageBox("文件不存在!",MB_OK|MB_ICONERROR);
return;
}
int nChunkCount=0; //文件块数
nChunkCount=FileLen/(1024*1024);
if(nChunkCount==0) nChunkCount++;
else
{
if(FileLen%nChunkCount!=0)
nChunkCount++;
}
char *date=new char[1024*1024];
for(int i=0;i<nChunkCount;i++) //分块发送
{
long nLeft;
if(i+1==nChunkCount) //最后一块
nLeft=FileLen-1024*1024*(nChunkCount-1);
else
nLeft=1024*1024;
int idx=0;
myFile.Read(date,nLeft);
while(nLeft>0)
{
int ret=send(server,&date[idx],nLeft,0);
if(ret==SOCKET_ERROR)
{
AfxMessageBox("网络断开!");
return;
}
nLeft-=ret;
idx+=ret;
}
}
myFile.Close();
AfxMessageBox("文件传输完成!");
delete[] date;
return;
文件结构:
typedef struct _SOCKET_STREAM_FILE_INFO {
TCHAR szFileTitle[128]; //文件的标题名
DWORD dwFileAttributes; //文件的属性
FILETIME ftCreationTime; //文件的创建时间
FILETIME ftLastAccessTime; //文件的最后访问时间
FILETIME ftLastWriteTime; //文件的最后修改时间
DWORD nFileSizeHigh; //文件大小高位
DWORD nFileSizeLow; //文件大小低位
DWORD dwReserved0; //保留,为0
DWORD dwReserved1; //保留,为0
} SOCKET_STREAM_FILE_INFO, * PSOCKET_STREAM_FILE_INFO;