int rc=0;
//初使化服务器地址
local.sin_family=AF_INET; local.sin_port=htons(1028);
local.sin_addr.S_un.S_addr=inet_addr(ip); m_socket=socket(AF_INET,SOCK_STREAM,0);
int ret;
//联接服务器
ret=connect(m_socket,(LPSOCKADDR)&local,sizeof(local)); //有错的话 if(ret<0){
AfxMessageBox(\联接错误\ closesocket(m_socket); return -1; }
//初使化命令
fileinfo fileinfo1; fileinfo1.len=n; fileinfo1.seek=50; fileinfo1.type=1; //发送命令
int aa=sendn(m_socket,(char*)&fileinfo1,100); if(aa<0){
closesocket(m_socket); return -1; }
//接收服务器传来的信息
aa=readn(m_socket,(char*)&fileinfo1,100); if(aa<0){
closesocket(m_socket); return -1; }
//关闭
shutdown(m_socket,2); closesocket(m_socket);
return 1; }
有了文件消息后我们就可以下载文件了。在主函数中,用法如下: //下载第clno个文件,并为它建一个新cdownload类
down[clno]=new cdownload(clno); //开始下载,并初使化
type=down[clno]->startask(clno); //建立各线程
createthread(clno); 下面介绍开始方法:
//开始方法
int cdownload::startask(int n) {
//读入文件长度
doinfo.filelen=zmfile[n].length; //读入名字
fname=zmfile[n].name; CString tmep; //初使化文件名
tmep.Format(\
//给主函数发消息 CString aaa;
aaa=\正在读取 \信息,马上开始下载。。。\\n\
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer
(0),1);
aaa.ReleaseBuffer();
//如果文件长度小于0就返回
if(doinfo.filelen<=0) return -1;
//建一个以.down结尾的文件记录文件信息 CString m_temp;
m_temp=fname+\
doinfo.name=m_temp; FILE* fp=NULL; CFile myfile;
//如果是第一次下载文件,初使化各记录文件
if((fp=fopen(m_temp,\ filerange[0]=0; //文件分块
for(int i=0;i if(i>0) filerange[i*2]=i*(doinfo.filelen/BLACK+1); filerange[i*2+1]=doinfo.filelen/BLACK+1; } filerange[BLACK*2-1]=doinfo.filelen-filerange[BLACK*2-2]; myfile.Open(m_temp,CFile::modeCreate|CFile::modeWrite | CFile::typeBina ry); //写入文件长度 myfile.Write(&doinfo.filelen,sizeof(int)); myfile.Close(); CString temp; for(int ii=0;ii //初使化各进程记录文件信息(以.downN结尾) temp.Format(\ m_temp=fname+temp; myfile.Open(m_temp,CFile::modeCreate|CFile::modeWrite | CFile::typeBina ry); //写入各进程文件信息 myfile.Write(&filerange[ii*2],sizeof(int)); myfile.Write(&filerange[ii*2+1],sizeof(int)); myfile.Close(); } ((CMainFrame*)::AfxGetMainWnd())->m_work.m_ListCtrl->AddItemtwo(n,2,0,0 ,0,doinfo.threadno); } else{ //如果文件已存在,说明是续传,读上次信息 CString temp; m_temp=fname+\ if((fp=fopen(m_temp,\ return 1; else fclose(fp); int bb; bb=0; //读各进程记录的信息 for(int ii=0;ii temp.Format(\ m_temp=fname+temp; myfile.Open(m_temp,CFile::modeRead | CFile::typeBinary); myfile.Read(&filerange[ii*2],sizeof(int)); myfile.Read(&filerange[ii*2+1],sizeof(int)); myfile.Close(); bb = bb+filerange[ii*2+1]; CString temp; } if(bb==0) return 1; doinfo.totle=doinfo.filelen-bb; ((CMainFrame*)::AfxGetMainWnd())->m_work.m_ListCtrl->AddItemtwo(n,2,doi nfo.totle,1,0,doinfo.threadno); } //建立下载结束进程timethread,以管现各进程结束时间。 DWORD dwthread; ::CreateThread(NULL,0,timethread,(LPVOID)this,0,&dwthread); return 0; } 下面介绍建立各进程函数,很简单: void CMainFrame::createthread(int threadno) { DWORD dwthread; //建立BLACK个进程 for(int i=0;i m_thread[threadno][i]= ::CreateThread(NULL,0,downthread,(LPVOID)down[t hreadno],0,&dwthread); } } downthread进程函数 DWORD WINAPI downthread(LPVOID lpparam) { cdownload* pthis=(cdownload*)lpparam; //进程引索+1 InterlockedIncrement(&pthis->m_index); //执行下载进程 pthis->threadfunc(pthis->m_index-1); return 1; } 下面介绍下载进程函数,最最核心的东西了 UINT cdownload::threadfunc(long index) { //初使化联接 sockaddr_in local; SOCKET m_socket; int rc=0; local.sin_family=AF_INET; local.sin_port=htons(1028); local.sin_addr.S_un.S_addr=inet_addr(ip); m_socket=socket(AF_INET,SOCK_STREAM,0); int ret; //读入缓存 char* m_buf=new char[SIZE]; int re,len2; fileinfo fileinfo1; //联接 ret=connect(m_socket,(LPSOCKADDR)&local,sizeof(local)); //读入各进程的下载信息 fileinfo1.len=filerange[index*2+1]; fileinfo1.seek=filerange[index*2]; fileinfo1.type=2; fileinfo1.fileno=doinfo.threadno; re=fileinfo1.len; //打开文件