您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 基于CS模式的winsock编程应用
***使用WINSOCK在客户方程序与服务方程序位于两台不同的机器上,在客户方通过指定服务方的IP地址和端口号来通讯。***下列代码仅供参考,同学们可自己参阅相应指导教材进行通信建立,之后可以下载工具软件进行开发。实验代码:#includestdafx.h#includeclient1.h#includecdownload.h#includeMainFrm.h#ifdef_DEBUG#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#definenewDEBUG_NEW#endif#defineSERVER_PORT3962#defineSIZE_OF_zmfile1080//关于此宏的定义,见server1项目。//Construction/Destruction//参数是:“可下载文件列表”List控件中当前列表项的索引。cdownload::cdownload(intthno1){m_fname=zm.zip;m_index=-1;doinfo.totle=0;doinfo.threadno=thno1;}cdownload::~cdownload(){}intcdownload::sendrequest(intn){//获取服务器信息sockaddr_inlocal;//建套接字SOCKETm_socket;intrc=0;//初使化服务器地址local.sin_family=AF_INET;local.sin_port=htons(SERVER_PORT);m_socket=socket(AF_INET,SOCK_STREAM,0);intret;//联接服务器ret=connect(m_socket,(LPSOCKADDR)&local,sizeof(local));//有错的话if(ret0){AfxMessageBox(联接错误);closesocket(m_socket);return-1;}//初使化命令fileinfofileinfo1;fileinfo1.len=n;fileinfo1.seek=50;fileinfo1.type=1;//发送命令intaa=sendn(m_socket,(char*)&fileinfo1,100);if(aa0){closesocket(m_socket);return-1;}//接收服务器传来的信息aa=readn(m_socket,(char*)&fileinfo1,100);if(aa0){closesocket(m_socket);return-1;}//关闭shutdown(m_socket,2);closesocket(m_socket);return1;}UINTcdownload::threadfunc(longindex){//初使化连接sockaddr_inlocal;SOCKETm_socket;intrc=0;local.sin_family=AF_INET;local.sin_port=htons(SERVER_PORT);local.sin_addr.S_un.S_addr=inet_addr(g_csIP);m_socket=socket(AF_INET,SOCK_STREAM,0);intret;//创建一个“读入缓冲区”,大小是20char*m_buf=newchar[SIZE];intremanent,len2;fileinfofileinfo1;//连接服务器端。ret=connect(m_socket,(LPSOCKADDR)&local,sizeof(local));//读入此线程的下载信息。fileinfo1.seek=filerange[index*2];//在文件中seek的位置。fileinfo1.len=filerange[index*2+1];//要下载的这一段文件的长度。remanent=fileinfo1.len;//发给服务器端的信息中,type=2,表示要求下载文件中的一段。(目前,服务器能识别的type的类型只有0和2这两种)fileinfo1.type=2;//这个字段,大概是“可下载文件列表”中的索引,可以用作对应的数组的下标。fileinfo1.fileno=doinfo.threadno;//destinationn.目的地(目标,指定)CFiledestFile;//用来保存要下载的文件的数据的文件,是“目标文件”。FILE*fp=NULL;//如果打开m_fname文件失败,说明此文件并不存在,也就是说:这是第一次下载。if((fp=fopen(m_fname,r))==NULL)//指定了CFile::modeCreate标记,表示一定要创建新文件。//调试后发现,m_fname中放的就是要下载的文件的真正的文件名。//注意:文件必须要以CFile::shareDenyNone的方式打开,只有这样,才能实现多个线程同时//打开此文件。destFile.Open(m_fname,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary|CFile::shareDenyNone);//如果此文件已经存在了,则说明这是另一个“正在下载此文件的”线程在运行,或者是续传。else{//这一句代码必须要加上,否则,在下载完文件之后,并且客户端程序没有退出的情况下,就//不能删除或移动或重命名下载的文件,因为fopen函数打开了文件,如果不关闭文件,则文件//就会被锁定住。fclose(fp);//addedbyyjkdestFile.Open(m_fname,CFile::modeWrite|CFile::typeBinary|CFile::shareDenyNone);}//文件指针移到指定位置,是从文件的开始位置开始偏移的。destFile.Seek(filerange[index*2],CFile::begin);//发消息给服务器,告诉它“可以传文件了”。sendn(m_socket,(char*)&fileinfo1,100);CFilemyfile;//这是一个辅助文件,是以“.down+N”为文件名后缀的。CStringcsTemp;CStringtemp;temp.Format(.down%d,index);//形成了一个辅助下载操作的文件的文件名“XX.down+N”。csTemp=m_fname+temp;//打开了“XX.down+N”文件myfile.Open(csTemp,CFile::modeWrite|CFile::typeBinary|CFile::shareDenyNone);//当还没下载完这一段文件的时候,就继续循环while(remanent0){len2=remanentSIZE?SIZE:remanent;intlen1=readn(m_socket,m_buf,len2);//如果接收数据的时候发生错误,则if(len1==SOCKET_ERROR){closesocket(m_socket);break;}destFile.Write(m_buf,len1);//更改要下载的这一段文件的长度,减去已经下载下来了的部分。filerange[index*2+1]-=len1;//前移在文件中seek的位置,也就是把已经下载下来了的那一部分移掉了。filerange[index*2]+=len1;//移动“文件指针”到辅助文件的开头位置。myfile.Seek(0,CFile::begin);//将当前的下载情况写入到辅助文件中,以备以后实现断点续传功能。myfile.Write(&filerange[index*2],sizeof(int));myfile.Write(&filerange[index*2+1],sizeof(int));//减去这次循环所读取的数据的长度。remanent=remanent-len1;//totle字段的含义:要被下载的文件段中,已经下载了的字节数。//对,下载完了一段之后,就需要把新下载的这一段的字节数加上去。doinfo.totle=doinfo.totle+len1;};//要下载的文件的片段下载完成了,做收尾工作。myfile.Close();//关闭辅助文件。destFile.Close();//关闭目标文件。delete[]m_buf;//删除用来从服务器端接收数据的缓冲区。shutdown(m_socket,2);//关闭连接socket。closesocket(m_socket);//addedbyyjk//如果剩余的字节数=0,则if(remanent=0)good[index]=TRUE;//设为true,大概表示:文件的这一段已经被成功下载下来了。return1;}//开始下载用户选中的那个“可下载的文件”。//参数是:要下载的文件的下标索引。intcdownload::startask(intn){//读入文件长度doinfo.filelen=zmfile[n].length;//读入文件名m_fname=zmfile[n].name;//给主窗体发消息CStringaaa;aaa=正在读取+m_fname+信息,马上开始下载。。。\n;AfxGetMainWnd()-SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);aaa.ReleaseBuffer();//如果文件长度小于0,则返回-1if(doinfo.filelen=0)return-1;//建一个以.down结尾的文件,用来记录文件信息CStringcsTemp;csTemp=m_fname+.down;//保存以.down结尾的文件之名。doinfo.name=csTemp;FILE*fp=NULL;CFilemyfile;if((fp=fopen(csTemp,r))==NULL){//addedbyyjkbegin//看看要下载的文件是否已经存在了,如果是已经存在了,就需要询问一下用户,是否要//重新下载,如果用户选择重新下载,将删除原来的文件。if((fp=fopen(m_fname,r))!=NULL){fclose(fp);//如果用户不想重新下载,就返回2,终止这次下载操作。if(::MessageBox(NULL,同名的文件已经存在了,如果选择“是”将覆盖原来的文件。你是否还要下载此文件?,YJK提醒用户,MB_YESNO|MB_ICONQUESTION)==IDNO)return2;//删除原来的文件,这样,就跟以前从没有下载过此文件一样了。DeleteFile(m_fname);}filerange[0]=0;for(inti=0;iBLOCK;i++){if(i0)//当i==1的时候,filerange[2]=50;//当i==2的时候,filerange[4]=100;//当i==3的时候,filerange[6]=150;filerange[i*2]=i*(doinfo.filelen/BLOCK+1);//加上1,是为了防止程序在遇到doinfo.filelen/BLOCK==0这种情况的时候,运行出错。filerange[i*2]=i*(doinfo.filelen/BLOCK);//addedbyyjk//当i==0的时候,filerange[1]=50;//当i==1的时候,filerange[3]=50;//当i==2的时候,filerange[5]=50;//当i==3的时候,filerange[7]=50;filerange[i*2+1]=doinfo.filelen/BLOCK+1;//filerange[i*2+1]=doinfo.filelen/BLOCK;//addedbyyjk}myfile.
本文标题:基于CS模式的winsock编程应用
链接地址:https://www.777doc.com/doc-5664837 .html