C++实现文件传输
c++实现文件传输之一:框架结构和界面实现在木马中文件管理的重要性,是无需质疑的,对于文件的管理,做到并不难,但做好却也不易在我们编写一个功能完整的“文件木马”其实现效果如图所示。
为了文章的完整性,我们将分为数篇来介绍,本文主要介绍程序的整体框架和界面实现,在以后的文章中将以此框架为基础实现详细的功能。
实现:枚举磁盘,枚举目录,获取文件信息上传文件,下载文件,执行文件,创建目录,删除目录等传输控制结构要实现客户端与服务端的通信,设计一个合理的传输控制结构,会使后面的工作轻松很多,为了使代码易读首先对要使用的命令进行预定义其各个命令定义如下#define GetDriver 0x01 //磁盘信息#define GetDirInfo 0x02 //目录信息#define ExecFile 0x03 //执行文件#define GetFile 0x04 //下载文件#define PutFile 0x05 //上传文件#define DelFile 0x06 //删除文件#define DelDir 0x07 //删除目录#define CreateDir 0x08 //创建目录#define FileInfo 0x09 //文件信息#define GetScreen 0x10 //查看屏幕在程序的网络通信中主要有操作命令 ,命令对像,和具体数据三部分,对于命令的传输定义如下结构typedef struct{int ID; //操作命令BYTE lparam[BUF_LEN*2]; //命令对像}COMMAND;因为在程序中打交道最多的就是文件,对文件的详细属性定义如下结构typedef struct{char FileName[MAX_PATH]; //文件名称int FileLen; //文件长度char Time[50]; //时间信息BOOL IsDir; //为目录否BOOL Error; //错误信息HICON hIcon; //图标句柄}FILEINFO;服务端结构服务端还是比较简单的其整体思路如下1.服务端循环接受连接,并把连接交给线程处理2.线程接受"命令数据",并跟据命令ID将命令对像和SOCKET句柄传给处理函数3.函数执行指定功能,并返回执行结果对整体结构的描述,我们用伪代码表述如下main(){ /*初示化设置......*/while(true){if(client=accept(server,(sockaddr *)&clientaddr,&len))//循环接受连接{CreateThread(NULL,NULL,SLisen,(LPVOID)client,NULL,NULL);//传递线程处理}}/*清理释放资源......*/WSACleanup();}服务端程序运行后循环接受连接,如果有新的连接就传递给新的线程处理,线程代码如下DWORD WINAPI SLisen(LPVOID lparam){SOCKET client=(SOCKET)lparam;COMMAND command;while(1){if(recv(client,(char*)&command,sizeof(command),0)==SOCKET_ERROR)//接受命令数据{cout<<"The Clinet Socket is Closed/n";break;}else{switch(command.ID)//判断命令ID{case GetDriver://将命令对像和SOCKET句柄传递给处理函数GetDriverProc (command,client);break;case DelFile:DelFileProc (command,client);break;/*其它命令......*/}}}}线程式的功能是接受客户端的"命令数据",并跟跟据命令ID 将命令对像传递给处理函数,由函数完成指定的功能以删除文件命令为例其函数格式如下DWORD DelFileProc (COMMAND command,SOCKET client){if(DeleteFile((char*)command.lparam)==0)//command.lparam为命令对像,这里为要删除的文件路径{send(client,"删除失败...");}else{send(client,"删除成功...");}}很容易看出,处理函数接受"命令对像"和客户端SOCKET句柄,执行后会把结果传递回去....客户端结构客户端结构的实现思路如下1.跟服务端建立连接2.发送用户命令3.启动一个线程,用于接受服务端的返回信息对整体结构的描述,我们用伪代码表述如下void CMyDlg::OnConnect(){if(connect(server,(SOCKADDR*)&serveraddr,sizeof(serveraddr))<0)//连接....{return ;}CreateThread(NULL,NULL,CLisen,this,NULL,NULL);//创建线程用于接受SERVER返回信息}对于用户发送的命令我们仍以删除文件为例说明其代码如下void CMyDlg::OnMenuDelFile(){HTREEITEM CurrentNode = m_tree.GetSelectedItem(); //取得选择的节点CString FullPath =GetFullPath(CurrentNode); //取得节点全目录COMMAND command;command.ID=DelFile; //设置命令为删除文件 //删除文件command.lparam=FullPath.LockBuffer()); //将路径加入命令对像send(server,command);}用于接受SERVER返回信息的线程,和服务端接受命令线程相似,这里就不再说明了,有兴趣可以看下源代码到这里程序的流程框架就介绍完了,下面我们再看一下程序的界面设置.界面实现程序的主界面如上图所示,主程序是一个对话框,主要包括一个树控件m_tree 和列表控件m_list分别用于显示磁盘目录和文件,在对话框初示化时用以下代码设置树控件的属性DWORD dwStyle = GetWindowLong(m_tree.m_hWnd,GWL_STYLE);dwStyle |=TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT; SetWindowLong(m_tree.m_hWnd,GWL_STYLE,dwStyle);对于列表框控件则没有太多要求,要留意的是,如果显示图标应该把Styles显示属性设置为ICONVC的做出的界面,常常让人有种摔键盘的冲动。
其实稍微留意一下其设置,也可以让它漂亮一些比如上图所示的界面就是经过简单设置得到的,而没有用其它类库,有点兴趣?其设置方法为:1.在对话框属性中设置Styles 的Border属性为Thin2.选重More Styles "可见" 属性3.选重Extended Styles的"静态边"属性这样再运行一下程序是不是感觉清新不少?到这里程序的主要结构框架和界面实现就介绍完了,下一篇将详细介绍其各种功能的实现c++实现文件传输之二在上一篇中,我们以经介绍了程序的流程和框架,在本篇将详细讨论各个功能的实现主要包括1.获取磁盘信息2.获取目录信息3.获取文件信息4.运行指定文件5.删除指定文件6.删除指定目录7.创建指定目录8.上传下载文件9.获取远程文件图标获取磁盘信息磁盘信息可以用API GetDriveType来实现,它以路径名作为参数(如C:/)返回磁盘类型,其实例代码如下DWORD GetDriverProc(COMMAND command,SOCKET client){for(char i='A';i<='Z';i++){char x[20]={i,':'};UINT Type=GetDriveType(x);if(Type==DRIVE_FIXED||Type==DRIVE_REMOVABLE||Type==DRIVE_CDROM) {/*返回处理结果...*/}}return 0;}GetDriveType可能返回的结果如下#define DRIVE_UNKNOWN 0 // 无效路径名#define DRIVE_NO_ROOT_DIR 1 // 无效路经,如无法找到的卷标#define DRIVE_REMOVABLE 2 // 可移动驱动器#define DRIVE_FIXED 3 // 固定的驱动器#define DRIVE_REMOTE 4 // 网络驱动器#define DRIVE_CDROM 5 // CD-ROM#define DRIVE_RAMDISK 6 // 随机存取(RAM)磁盘在上面的实例代码中我们只取,硬盘,光驱和移动磁盘获取目录信息这里只要枚举用户指定的目录就可以了,其实例代码如下:DWORD GetDirInfoProc(COMMAND command,SOCKET client){/*command为要枚举的路径如(C:/)client为返回结果的SOCKET句柄*/FILEINFO fi;memset((char*)&fi,0,sizeof(fi));strcat((char*)command.lparam,"*.*");//枚举所有文件CFileFind file;BOOL bContinue = file.FindFile((char*)command.lparam);while(bContinue){memset((char*)&fi,0,sizeof(fi));bContinue = file.FindNextFile();if(file.IsDirectory()) //为目录{fi.IsDir=true;}strcpy(fi.FileName,file.GetFileName().LockBuffer()); //保存文件名称if(send(client,(char*)&fi,sizeof(cmd),0)==SOCKET_ERROR){cout << "Send Dir is Error/n";}}return 0;}获取文件信息以下实例代码用来获取文件的名称,路径,时间,属性等信息DWORD FileInfoProc (COMMAND command,SOCKET client){/*command为要查看的文件如(C:/TEST.EXE)client为返回结果的SOCKET句柄*/ FILEINFO fi;HANDLE hFile;WIN32_FIND_DATA WFD;memset((char*)&WFD,0,sizeof(WFD));if((hFile=FindFirstFile((char*)command.lparam,&WFD))==INVALID_HANDLE_ VALUE) //查看文件属性{fi.Error=true;return 0;}//得到文件的相关信息SHGetFileInfo(WFD.cFileName,FILE_ATTRIBUTE_NORMAL,&shfi, sizeof(shfi),SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_TYPENAME );strcpy(fi.FileName,(char*)command.lparam); //文件路径FileLen=(WFD.nFileSizeHigh*MAXDWORD+WFD.nFileSizeLow)/1024; //文件长度fi.FileLen=FileLen;//转化格林时间到本地时间FileTimeToLocalFileTime(&WFD.ftLastWriteTime,&localtime); FileTimeToSystemTime(&localtime,&systime);//文件修改时间sprintf(stime,"%4d-%02d-%02d %02d:%02d:%02d",systime.wYear,systime.wMonth,systime.wDay,systime.wHour,systime.wMinute,systime.wSecond);if(GetFileAttributes((char*)command.lparam)&FILE_ATTRIBUTE_HIDDEN) {/*隐藏文件...*/}elseif(GetFileAttributes((char*)command.lparam)&FILE_ATTRIBUTE_READONLY) {/*只读文件...*/}send(client,(char*)&fi,sizeof(fi),0);FindClose(hFile);return 0;}运行指定文件运行文件有以下几种方法 1.WinExec 2.ShellExecute 3.CreateProcess这里使用的是ShellExecute其实例代码如下DWORD ExecFileProc (COMMAND command,SOCKET client){/*command为要运行的文件路径如(C:/TEST.EXE)client为返回结果的SOCKET 句柄*/COMMAND cmd;memset((char*)&cmd,0,sizeof(cmd));cmd.ID=ExecFile;if(ShellExecute(NULL,"open",(char*)command.lparam,NULL,NULL,SW_HIDE)< (HINSTANCE)32){strcpy((char*)cmd.lparam,"文件执行失败!");send(client,(char*)&cmd,sizeof(cmd),0);}else{strcpy((char*)cmd.lparam,"文件执行成功!");send(client,(char*)&cmd,sizeof(cmd),0);}return 0;}API函数ShellExecute原形为:HINSTANCE ShellExecute(HWND hwnd, //窗口句柄LPCTSTR lpOperation, //操作类型LPCTSTR lpFile, //文件指针LPCTSTR lpParameters, //文件参数LPCTSTR lpDirectory, //缺省目录INT nShowCmd //显示方式);这是一个相当有意思的函数,在调用此函数时只须指定要执行的文件名,而不必管用什么程序去打开或执行文件,WINDOWS会自动根据要打开或执行的文件去判断该如何执行文件或用什么程序去打开文件,如果要求不高的话比CreateProcess要好用的多,如果想做出像NCPH和灰鸽子那样带参数执行的话,其实也不难只要指定lpParameters为执行参数就可了删除指定文件DWORD DelFileProc (COMMAND command,SOCKET client){/*command为要删除的文件路径如(C:/TEST.EXE)client为返回结果的SOCKET 句柄*/COMMAND cmd;memset((char*)&cmd,0,sizeof(cmd));cmd.ID=DelFile;SetFileAttributes((char*)command.lparam,FILE_ATTRIBUTE_NORMAL); //去掉文件的系统和隐藏属性if(DeleteFile((char*)command.lparam)==0){strcpy((char*)cmd.lparam,"文件删除失败!");send(client,(char*)&cmd,sizeof(cmd),0);}else{strcpy((char*)cmd.lparam,"文件删除成功!");send(client,(char*)&cmd,sizeof(cmd),0);}return 0;}需要注意的是在 DeleteFile前应该去文件的系统和隐藏属性,否则会删除失败删除目录可以用RemoveDirectory函数删除目录,但是RemoveDirectory有个缺点就是只能删除为空的的目录,对于不为空的目录就无能为力了,想要删除不无空的目录可以使用下面的实例代码BOOL DeleteDirectory(char *DirName){CFileFind tempFind;char tempFileFind[200];sprintf(tempFileFind,"%s*.*",DirName);BOOL IsFinded=(BOOL)tempFind.FindFile(tempFileFind);while(IsFinded){IsFinded=(BOOL)tempFind.FindNextFile();if(!tempFind.IsDots()){char foundFileName[200];strcpy(foundFileName,tempFind.GetFileName().GetBuffer(200));if(tempFind.IsDirectory()){char tempDir[200];sprintf(tempDir,"%s//%s",DirName,foundFileName);DeleteDirectory(tempDir);}else{char tempFileName[200];sprintf(tempFileName,"%s//%s",DirName,foundFileName); SetFileAttributes(tempFileName,FILE_ATTRIBUTE_NORMAL); //去掉文件的系统和隐藏属性DeleteFile(tempFileName);cout <<"now delete "<<tempFileName<<"/n";}}}tempFind.Close();if(!RemoveDirectory(DirName)){return FALSE;return TRUE;}这个函数的代码可以参照上面枚举目录的代码来看,它的原理就是枚举目录下的所有文件并删除,最后删除指定目录,成功返回TRUE失败则返回FALSE,这段代码可以直使用,但要小心使用,因为我在传参数时的失误结果把整个D盘差点清空了..........创建目录实例代码如下:DWORD CreateDirProc (COMMAND command,SOCKET client){/*command为要创建目录的路径如(C:/)client为返回结果的SOCKET句柄*/ COMMAND cmd;memset((char*)&cmd,0,sizeof(cmd));cmd.ID=CreateDir;if(::CreateDirectory((char*)command.lparam,NULL)){strcpy((char*)cmd.lparam,"创建目录成功!");send(client,(char*)&cmd,sizeof(cmd),0);}else{strcpy((char*)cmd.lparam,"创建目录失败!可能有重名文件或文件夹");send(client,(char*)&cmd,sizeof(cmd),0);}return 0;}在创建目录时应该注意几点,首先创始目录的上层目录必须是存在的,比如想创建C:/DIR1/DIR2目录,要求DIR1是必须存在,用CreateDirectory并不能创建多级目录.再者不可以存在和要创建目录同名的目录和文件因为在磁盘上目录和文件的存放格式是相同的,惟一不同的是目录的属性与文件属性不同(FILE_ATTRIBUTE_DIRECTORY属性),所在即使有同名文件也会创始失败.上传下载文件上传下载是是文件管理的重点所在,在这里按文件的大小,分两种情况讨论文件的传输方法小文件的传输相对比较简单可按以下方法进行1.首先发送文件长度和名称2.跟据文件长度建立缓冲区3.读取整个文件到缓冲区4.发送缓冲区里的容其实现代码如下:CFile file;FILEINFO fileinfo;if(file.Open(path,CFile::modeRead|CFile::typeBinary)){fileinfo.FileLen=file.GetLength(); //文件长度strcpy(fileinfo.FileName,file.GetFileName()); //文件名称send(client,(char*)&fileinfo,sizeof(fileinfo),0); //发送长度和名称char *date=new char[fileinfo.FileLen]; //分配和文件长度相同的缓冲区int nLeft=fileinfo.FileLen;int idx=0;file.Read(date,fileinfo.FileLen); //读整个文件到缓冲区while(nLeft>0){int ret=send(client,&date[idx],nLeft,0); //发送文件if(ret==SOCKET_ERROR){break;}nLeft-=ret;idx+=ret;}file.Close();delete[] date;}跟据上面的实例相信大家可以领悟到文件传输的基本原理和方法,虽然很简单但用它传输小文件还是非常实用的大文件传输方法用上面的方法传输小文件还可以,但是大文件呢?比如一个500M的电影.上面的方法就会力不从心了因为按思路要创建一个跟文件大小相同的缓冲区,显然这是不太现实的,我们就得采用另种方法了,在这里我们使用分块文件传输,所谓分块是指把大文件分成若干小文件,然后传输,比如设定每块大小为64KB其思路如下1.取得文件长度和名称2.跟据长度/64KB计算文件块数3.分配64KB缓冲区4.读文件到缓冲区5.发送缓冲的数据6.重复4,5两步直到发完所有数据其实现代码如下:#define CHUNK_SIZE (64*1024) //分为64K块传输DWORD GetFileProc (COMMAND command,SOCKET client){/*command为要下载文件的路径如(C:/TEST.EXE)client为发送文件的SOCKET 句柄*/COMMAND cmd;FILEINFO fi;memset((char*)&fi,0,sizeof(fi));memset((char*)&cmd,0,sizeof(cmd));cmd.ID=GetFile;CFile file;int nChunkCount=0; //文件块数if(file.Open((char*)command.lparam,CFile::modeRead|CFile::typeBinary) )//打开文件{int FileLen=file.GetLength(); //取文件长度fi.FileLen=file.GetLength();strcpy((char*)fi.FileName,file.GetFileName()); //取文件名称memcpy((char*)&cmd.lparam,(char*)&fi,sizeof(fi));send(client,(char*)&cmd,sizeof(cmd),0); //发送文件名称和长度nChunkCount=FileLen/CHUNK_SIZE; //文件块数if(FileLen%nChunkCount!=0)nChunkCount++;char *date=new char[CHUNK_SIZE]; //创建数据缓冲区for(int i=0;i<nChunkCount;i++) //分为nChunkCount块发送{int nLeft;if(i+1==nChunkCount) //最后一块nLeft=FileLen-CHUNK_SIZE*(nChunkCount-1);elsenLeft=CHUNK_SIZE;int idx=0;file.Read(date,CHUNK_SIZE); //读取文件while(nLeft>0){int ret=send(client,&date[idx],nLeft,0);//发送文件if(ret==SOCKET_ERROR){break;}nLeft-=ret;idx+=ret;}}file.Close();delete[] date;}return 0;}这样文件传输部分就完成了,止于客户端的实现于上面代码其本相同,只是由读文件变为写文件,详细请参考源代码获取远程ICO文件图标我们在文件列表框中需要显示文件的图标,但远程文件的ICO图标是无法直接得到的猛若RADMIN 黑洞者也没有到(对于EXE文件只显示可执行程序图示),当然了也不见的决对没有......我们可以通过如下变通方法得到:就是跟据文件的扩展名,从本地注册表中查找对应的程序图标不过这也有它的缺点对于EXE文件它只能显示一个可执行文件的图示,而且只能显示注册过的图示比如,如果本机装有WINRAR那么就可以识别.RAR的文件图示,否则就无法识别...实现方法CImageList m_ImageList;m_ImageList.Create(32,32,ILC_COLOR32,10,30); //创建图示m_list.SetImageList(&m_ImageList,LVSIL_NORMAL); //与列表控件相关连SHFILEINFO info;memset((char*)&info,0,sizeof(info));SHGetFileInfo(fi->FileName,0,&info,sizeof(&info), SHGFI_ICON|SHGF I_USEFILEATTRIBUTES);//关键所在int i = m_ImageList.Add(info.hIcon);m_list.InsertItem(i,fi->FileName,i);原来我试图在Server端通过上面的代码把info.hIcon句柄保存下来,然后放到Client,在单台电脑上很好使,但Server在另一台电脑上时就玩完了,因为info.hIcon里保存的句柄是个索引而每台机器上的索引是不相同的所以直接导致的结果就是:什么也显示不出来....c++实现文件传输之三:断点续传与多线程传输转继木马编程DIY的上两篇,现在我们开始讨论断点续传与多线程文件传输的实现.其实这两项功能是下载软件所必不可少的功能了,现在我们把它加到自己的木马中来感受感受.提到多线程下载,首先向网络蚂蚁的作者洪以容前辈致敬,正是由于网络蚂蚁而使得多线程下载被关注并流行起来.在这本篇文章中我们将简单的实现支持断点续传和多线程传输的程序.为了更清晰的说明问题,我们将断点续传与多线程传输分别用两个程序来实现多线程传输实现实现原理将源文件按长度为分为N块文件,然后开辟N个线程,每个线程传输一块,最后合并所有线线程文件.比如一个文件500M我们按长度可以分5个线程传输.第一线程从0-100M,第二线程从100M-200M......最后合并5个线程文件.实现流程1.客户端向服务端请求文件信息(名称,长度)2.客户端跟据文件长度开辟N个线程连接服务端3.服务端开辟新的线程与客户端通信并传输文件4.客户端将每线程数据保存到一个文件5.合并所有线程文件编码实现大体说来就是按以上步骤进行,详细的实现和一些要点,我们跟据以上流程在编码中实现结构定义在通信过程中需要传递的信息包括文件名称,文件长度,文件偏移,操作指令等信息,为了方便操作我们定义如下结构代码:typedef struct{char Name[100]; //文件名称int FileLen;//文件长度int CMD;//操作指令int seek;//线程开始位置SOCKET sockid;}FILEINFO;1.请求文件信息客户端代码如下代码:FILEINFO fi;memset((char*)&fi,0,sizeof(fi));fi.CMD=1; //得到文件信息if(send(client,(char*)&fi,sizeof(fi),0)==SOCKET_ERROR){cout<<"Send Get FileInfo Error/n";}服务端代码如下while(true){SOCKET client;if(client=accept(server,(sockaddr *)&clientaddr,&len)){FILEINFO RecvFileInfo;memset((char*)&RecvFil eInfo,0,sizeof(RecvFileInfo));if(recv(client,(char*) &RecvFileInfo,sizeof(RecvFileInfo),0)==SOCKET_ERROR){cout<< "The Clinet Socket is Closed/n";break;}else{EnterC riticalSection(&CS); //进入临界区memcpy ((char*)&TempFileInfo,(char*)&RecvFileInfo,sizeof(RecvFileInfo));switch (TempFileInfo.CMD){case 1:GetInfoProc (client);break;case 2:TempFileInfo.sockid=client;CreateThread(NULL,NULL,GetFileProc,NULL, NULL,NULL);break;}LeaveC riticalSection(&CS); //离开临界区}}}在这里服务端循环接受连接,并跟据TempFileInfo.CMD来判断客户端的请求类型,1为请求文件信息,2为下载文件因为在下载文件的请求中,需要开辟新的线程,并传递文件偏移和文件大小等信息,所以需要对线程同步.这里使用临界区其文件信息函数GetInfoProc代码如下代码:DWORD GetInfoProc(SOCKET client){CFile file;if(file.Open(FileName,CFile::modeRead|CFile::typeBinar y)){int FileLen=file.GetLength();if(send(client,(char*)&FileLen,sizeof( FileLen),0)==SOCKET_ERROR){cout<< "Send FileLen Error/n";}else{cout<< "The Filelen is "<<FileLen<<"/n/n";}}return 0;}这里主要是向客户端传递文件长度,而客户端收到长度后则开辟线程进行连接传输文件2.客户端跟据长度开辟线程其实现代码如下代码:FILEINFO FI;int FileLen=0;if(recv(client,(char*)&FileLen,sizeof(FileLen),0)==SOC KET_ERROR)//接受文件长度{cout<<"Recv FileLen Error/n";}else{cout<<"FileLen is "<<FileLen<<"/n";int COUNT_SIZE=FileLen/5; / /每线程传输大小for(int i=0;i<5;i++)//分5个线程传输{EnterCriticalSection(& CS); //进入临界区memset((char*)&FI,0,si zeof(FI));FI.CMD=2;//请求下载文件FI.seek=i*COUNT_SIZE;//线程文件偏移if(i+1==5)//最后一线程长度为总长度减前4个线程长度{FI.Fil eLen=FileLen-COUNT_SIZE*i;}else{FI.Fil eLen=COUNT_SIZE;}Thread=CreateThread(NU LL,NULL,GetFileThread,&i,NULL,NULL);Sleep(500);LeaveCriticalSection(& CS); //离开临界区}}WaitForMultipleObjects(5,Thread,true,INFINITE);//等所有线程结束这里默认开辟5个线程传输,当然可以改为想要的线程数目,仍然用临界区来实现线程的同步问题3.服务端开辟线程传输数据在1.请求文件信息中以说明了服务端的结构,这里主要介绍线程函数的实现,其代码如下代码:DWORD WINAPI GetFileProc(LPVOID lparam){EnterCriticalSection(&CS);//进入临界区int FileLen=TempFileInfo.FileLen;int Seek=TempFileInfo.seek;SOCKET client=TempFileInfo.sockid;LeaveCriticalSection(&CS);//离开临界区CFile file;if(file.Open(FileName,CFile::modeRead|CFile::typeBinar y)){file.Seek(Seek,CFile::begin);//指针移至偏移位置char *date=new char[FileLen];int nLeft=FileLen;int idx=0;file.Read(date,FileLen);while(nLeft>0){int ret=send(client,&date[idx],nLeft,0);if(ret==SOCKET_ERROR){cout<< "Send Date Error /n";break;}nLeft-=ret;idx+=ret;}file.Close();delete[] date;}else{cout<<"open the file error/n";}closesocket(client);return 0;}还是比较简单的,主要是获取线程的文件长度和偏移,并移动文件指针到偏移处,最后读取发送数据,而客户端接受数据并写入文件.4.客户端将线程数据保存到文件GetFileThread的实现代码如下代码:DWORD WINAPI GetFileThread(LPVOID lparam){char TempName[MAX_PATH];sprintf(TempName,"TempFile%d",*(DWORD*)lparam);//每线程的文件名为"TempName"+线程数SOCKET client;SOCKADDR_IN serveraddr;int port=5555;client=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);serveraddr.sin_family=AF_INET;serveraddr.sin_port=htons(port);serveraddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");if(connect(client,(SOCKADDR*)&serveraddr,sizeof(server addr))==INVALID_SOCKET){cout<<"Connect Server Error/n";}EnterCriticalSection(&CS);//进入临界区if(send(client,(char*)&FI,sizeof(FI),0)==SOCKET_ERROR){cout<<"Send GetFile Error/n";return 0;}CFile file;int FileLen=FI.FileLen; //文件长度int Seek=FI.seek; //文件偏移LeaveCriticalSection(&CS);//离开临界区if(file.Open(TempName,CFile::modeWrite|CFile::typeBina ry|CFile::modeCreate)){char *date = new char[FileLen];int nLeft=FileLen;int idx=0;while(nLeft>0){int ret=recv(client,&date[idx],nLeft,0);if(ret==SOCKET_ERROR){cout<< "Recv Date Error";break;}idx+=ret;nLeft-=ret;}file.Write(date,FileLen);file.Close();delete[] date;}else{cout<<"Create File Error/n";}return 0;}在此线程函数中,将每线程传输的数据存为一个文件,文件名为"TempName"+线程数,只所以存成单独的文件是因为比较直观且容易理解,但如果文件很大的话这个方法并不好,因为合并文件又会花费很多时间,另一个方法是创始一个文件,让每个线程写入文件的不同偏移,这样就可以不必单独合并文件了,但要记得打开文件时加入CFile::shareDenyNone属性.这样整个过程就完成了.最后一步合并线程文件5.合并线程文件代码:int UniteFile() //合并线程文件{cout<<"Now is Unite Fileing.../n";int len;char *date;CFile file;CFile file0;/*其它文件......*/if(file.Open(FileName,CFile::modeCreate|CFile::typeBin ary|CFile::modeWrite))//创建文件{file0.Open("TempFile0",CFile::modeRead |CFile::typeBinary);//合并第一线程文件len=file0.GetLength();date=new char[len];file0.Read(date,len);file.SeekToEnd();file.Write(date,len);file1.Open("TempFile1",CFile::modeRead|CFile::typeBinary);//合并第二线程文件len=file1.GetLength();date=new char[len];file1.Read(date,len);file.SeekToEnd();file.Write(date,len);/*合并其它线程......*/file0.Close();file1.Close();/*.......*/delete[] date;return true;}else{return false;}}这个简单,就是打开一个文件读取到缓冲区,写入文件,再打开第二个......现在多线程传输部分就介绍完了下面讨论断断点续传的实现c++实现文件传输之四:断点传输所谓的断点续传就是指:文件在传输过程式中被中断后,在重新传输时,可以从上次的断点处开始传输,这样就可节省时间,和其它资源.实现关键在这里有两个关键点,其一是检测本地已经下载的文件长度和断点值,其二是在服务端调整文件指针到断点处实现方法我们用一个简单的方法来实现断点续传的功能.在传输文件的时候创建一个临时文件用来存放文件的断点位置在每次发送接受文件时,先检查有没有临时文件,如果有的话就从临时文件中读取断点值,并把文件指针移动到断点位置开始传输,这样便可以做到断点续传了实现流程首次传输其流程如下1.服务端向客户端传递文件名称和文件长度2.跟据文件长度计算文件块数(文件分块传输请参照第二篇文章)3.客户端将传输的块数写入临时文件(做为断点值)4.若文件传输成功则删除临时文件首次传输失败后将按以下流程进行1.客户端从临时文件读取断点值并发送给服务端2.服务端与客户端将文件指针移至断点处3.从断点处传输文件编码实现因为程序代码并不复杂,且注释也比较详细,这里就给出完整的实现其服务端实现代码如下代码:int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){cout<<"/t/t服务端-断点续传"<<"/t 作者:冷风/n/n"<<"请输入被下载的文件路径如 C://File.rar /n/n"<<"文件路径: ";cin >>FilePath;/*这部分为网络参数与设置,详细请参照源代码......*/while(true){if(client=accept(server,(sockaddr *)&clientaddr,&len)){cout<<"have one connect/n";int nCurrentPos=0;//接受断点值if(recv(client,(char*) &nCurrentPos,sizeof(nCurrentPos),0)==SOCKET_ERROR){cout<< "The Clinet Socket is Closed/n";break;}else{cout<< "The Currentpos is The"<<nCurrentPos<<"/n";GetFil eProc (nCurrentPos,client);}}}closesocket(server);closesocket(client);WSACleanup();return 0;return 0;}DWORD GetFileProc (int nCurrentPos,SOCKET client){cout <<"Get File Proc is ok/n";CFile file;int nChunkCount=0;//文件块数if(file.Open(FilePath,CFile::modeRead|CFile::typeBinar y)){if(nCurrentPos!=0){file.Seek(nCurrentPos* CHUNK_SIZE,CFile::begin); //文件指针移至断点处cout<<"file seek is "<<nCurrentPos*CHUNK_SIZE<<"/n";}int FileLen=file.GetLength();nChunkCount=FileLen/CHUNK_SIZE;//文件块数if(FileLen%nChunkCount!=0)nChunkCount++;send(client,(char*)&FileLen,sizeof(Fil eLen),0); //发送文件长度char *date=new char[CHUNK_SIZE];for(int i=nCurrentPos;i<nChunkCount;i++) //从断点处分块发送{cout<<"send the count"<<i<<"/n";int nLeft;if(i+1==nChunkCount)//最后一块nLeft= FileLen-CHUNK_SIZE*(nChunkCount-1);elsenLeft= CHUNK_SIZE;int idx=0;file.Read(date,CHUNK_S IZE);while(nLeft>0){intret=send(client,&date[idx],nLeft,0);if(ret ==SOCKET_ERROR){ cout<<"Send The Date Error /n";break;}nLeft-=ret;idx+=r et;}}file.Close();delete[] date;}else{cout<<"open the file error/n";}return 0;}客户端实现代码如下代码:int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){cout<<"/t/t客户端-断点续传"<<"/t 作者:冷风/n/n"<<"请输入保存文件的路径如 C://Save.RAR /n/n"<<"文件路径: ";cin >>FilePath;/*网络参数初示化,详细请参照源代码......*/if(connect(client,(SOCKADDR*)&serveraddr,sizeof(server addr))==INVALID_SOCKET){cout<<"Connect Server Error";return 0;}int FileLen=0;int nCurrentPos=0; //断点位置UINT OpenFlags;CFile PosFile;if(PosFile.Open("PosFile.temp",CFile::modeRead|CFile:: typeBinary))//如果有临时文件则读取断点{PosFile.Read((char*)&nCurrentPos,sizeo f(nCurrentPos)); //读取断点位置cout<<"The File Pos is "<<nCurrentPos<<"/n";nCurrentPos=nCurrentPos+1;//从断点的下一块开始PosFile.Close();send(client,(char*)&nCurrentPos,sizeof (nCurrentPos),0); //发送断点值OpenFlags=CFile::modeWrite|CFile::type Binary; //文件为可写}else{send(client,(char*)&nCurrentPos,sizeof (nCurrentPos),0); //无断点文件nCurrentPos为0OpenFlags=CFile::modeWrite|CFile::type Binary|CFile::modeCreate;//创建文件方式}if(recv(client,(char*)&FileLen,sizeof(FileLen),0)!=0)/ /接受文件长度{int nChu nkCount;CFile file;nChunkCount=FileLen/CHUNK_SIZE;//计算文件块数if(FileLen%nChunkCount!=0){nChunkCount++;}if(file.Open(FilePath,OpenFlags)){file.Seek(nCurrentPos* CHUNK_SIZE,CFile::begin); //文件指针移至断点处char *date = new char[CHUNK_SIZE];for(int i=nCurrentPos;i<nChunkCount;i++) //从断点处开始写入文件{cout<< "Recv The Chunk is "<<i<<"/n";int nLeft;if(i+1 ==nChunkCount)//最后一块nLeft=FileLen-CHUNK_SIZE*(nChunkCount-1);elsenLeft=CHUNK_SIZE;int idx=0;while( nLeft>0){ int ret=recv(client,&date[idx],nLeft,0);if(ret==SOCKET_ERROR){cout<<"Recv Date Error";return 0;}idx+=ret;nLeft-=ret;}file.W rite(date,CHUNK_SIZE);CFile PosFile; //将断点写入PosFile.temp文件int seekpos=i+1;if(Pos File.Open("PosFile.temp",CFile::modeWrite|CFile::typeBinary|CFile::mo deCreate));{PosFile.Write((char*)&seekpos,sizeof(seekpos));PosFile.Close();}}file.Close();delete[] date;}if(DeleteFile("PosFile.temp")!=0){cout<<"文件传输完成";}}return 0;}客户端运行时会试图打开临时文件,如果存在则读取断点值,如果不存在则断点为0,打开文件后将文件指针移至断点处开始接受数据,每接受一块就把当前块的数值存入临时文件.其实现代码比较简单结合上面的流程介绍看代码应该没什么难度,所以我也就不画蛇添足了.。
c语言文件拷贝函数
c语言文件拷贝函数摘要:1.文件拷贝函数的背景和意义2.文件拷贝函数的原理3.文件拷贝函数的实现4.文件拷贝函数的应用场景5.文件拷贝函数的性能和优化正文:C语言是一种广泛应用于系统编程和应用开发的编程语言,它提供了丰富的文件操作函数,包括文件读写、文件定位等。
在这些函数中,文件拷贝函数是实现文件传输和备份的重要工具。
本文将详细介绍C语言文件拷贝函数的相关知识。
文件拷贝函数的原理是通过读取源文件的数据,将其写入目标文件。
在C 语言中,有两个常用的文件拷贝函数:fread()和fcopy()。
其中,fread()函数用于从文件中读取数据,fcopy()函数用于将数据从源文件拷贝到目标文件。
文件拷贝函数的实现过程可以分为以下几个步骤:1.打开源文件和目标文件,如果目标文件不存在,需要创建目标文件。
2.使用fread()函数从源文件中读取数据,将数据存储在缓冲区。
3.使用fwrite()函数将缓冲区中的数据写入目标文件。
4.重复步骤2和3,直到文件结束。
5.关闭源文件和目标文件。
文件拷贝函数的应用场景包括:1.文件备份:将重要的文件拷贝到另一个地方,以防数据丢失。
2.文件传输:在不同设备之间传输文件。
3.文件合并:将多个文件合并成一个文件。
文件拷贝函数的性能和优化主要取决于磁盘IO性能和CPU性能。
为了提高文件拷贝速度,可以采用以下方法:1.使用多线程或多进程并行拷贝,充分利用CPU资源。
2.使用内存映射文件技术,将文件数据映射到内存,减少磁盘IO次数。
3.对大文件进行分块拷贝,减小单次读写的数据量,提高磁盘缓存利用率。
总之,C语言文件拷贝函数是文件操作中的重要工具,了解其原理和应用场景有助于更好地利用文件拷贝函数解决实际问题。
ymodem协议 c例程
ymodem协议 c例程协议目的本协议旨在规范双方在Ymodem协议下的文件传输过程,并定义相关的技术和操作要求,以确保数据的准确传输和系统的兼容性。
协议双方信息甲方(传输方):____________________________乙方(接收方):____________________________协议内容3.1 Ymodem协议定义3.1.1 Ymodem协议是一种用于数据传输的协议,基于Xmodem协议的扩展,支持批量文件传输。
3.1.2 本协议中所涉及的Ymodem协议版本为____________________________。
3.2 文件传输要求3.2.1 传输文件的格式应为____________________________。
3.2.2 文件传输过程中,文件名及文件大小应准确无误,数据应完整无损。
3.3 传输流程3.3.1 甲方应在传输前向乙方发送文件名和文件大小。
3.3.2 乙方确认接收文件,并发送确认信号。
3.3.3 甲方开始传输文件,文件传输过程中应每传输完一部分数据,甲方应发送数据块头。
3.3.4 乙方收到数据块后,应进行校验并返回应答信号。
3.3.5 传输完成后,乙方应向甲方发送结束信号以确认文件接收完毕。
技术规格4.1 数据块大小4.1.1 数据块的大小应为____________________________字节。
4.2 校验方式4.2.1 文件数据块的校验应使用____________________________校验方法。
4.3 超时设置4.3.1 超时设置应为____________________________秒,超时后应重新传输数据块。
权利与义务5.1 甲方的权利与义务5.1.1 甲方应按协议规定的格式和要求进行数据传输。
5.1.2 甲方应确保传输数据的准确性和完整性。
5.2 乙方的权利与义务5.2.1 乙方应按协议规定的方式接收数据。
5.2.2 乙方应在接收到每个数据块后进行校验,并及时返回应答信号。
Python实现TCP文件传输
Python实现TCP文件传输TCP (Transmission Control Protocol) 是一种可靠的传输协议,常用于在网络上传输数据。
通过使用Python的内置socket库,可以轻松实现TCP文件传输。
在TCP文件传输过程中,需要一个服务器和一个客户端。
服务器负责接收文件,而客户端负责发送文件。
下面是一个简单的Python程序,实现了TCP文件传输的服务器端:```pythonimport socket#服务器IP地址和端口号SERVER_HOST='127.0.0.1'#一次接收的最大数据量BUFFER_SIZE=4096# 创建一个socket对象server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 将服务器socket对象绑定到指定的IP地址和端口号上server_socket.bind((SERVER_HOST, SERVER_PORT))# 使服务器socket对象监听传入的连接server_socket.listen(5)print(f"服务器正在监听地址 {SERVER_HOST}:{SERVER_PORT}...") #接受客户端连接client_socket, address = server_socket.acceptprint(f"来自地址 {address} 的连接已建立!")#接收客户端发送的文件名file_name = client_socket.recv(BUFFER_SIZE).decode#打开文件,准备写入file = open(file_name, 'wb')#开始接收文件数据并写入文件while True:data = client_socket.recv(BUFFER_SIZE)if not data:breakfile.write(data)# 关闭文件和socket连接file.closeclient_socket.closeserver_socket.closeprint("文件接收完毕!")```在以上代码中,我们首先创建了一个服务器socket对象,并将其绑定到指定的IP地址和端口号上。
C-2-04-文件同步与分享利器Resilio Sync
文件同步与分享利器Resilio Sync1.问题提出与软件介绍当自己需要多设备同步或与同事需要频繁共享文件时,QQ 或微信的文件传输相对是不够用的。
使用百度云这样的网盘服务,来保持文件始终最新会是更省事的方法。
不过,通过这些网盘传文件,基本都需要把文件上传到服务器再进行同步。
BitTorrent 公司推出Resilio Sync 采用了不一样的解决方法:不需要把文件上传到云端服务器,而是基于BT传输技术,通过P2P 的方式,直接将文件从你的设备传到对方设备上,它不限速、不限文件大小、不需要注册账号。
这种可以实现去中心化的传输。
软件支持各种桌面/移动/NAS系统。
我们可以用该软件实现我们本地多设备,多数据的同步,以提高我们随时随地调用知识和生产知识的需要。
2.下载与安装Resilio Sync 是简单易用的多平台文件同步软件,支持全平台。
登录官网https:///下载安装文件。
或百度进行搜索下载。
下载安装完成后,打开Resilio Sync 软件,就可以看到如图1所示的界面:图1上面一行是操作区。
点击最左边的倒三角按钮,可以新建自己的分享和添加别人的分享。
新建分享文件夹有三种模式:标准文件夹、高级文件夹、加密文件夹。
如图2图2标准文件夹:可设置只读和读写,但无法更改访问权限或控制共享文件的人。
高级文件夹:分享权限更多。
只有升级到收费的Pro 版可用。
加密文件夹:除标准功能外,可以使用加密密钥加密数据,通过加密密钥同步的文件不可读取。
点击“输入密钥或链接”可以添加别人的分享。
如果是APP 还可以通过扫描二维码的方式添加分享。
操作区右边有五个图标,从左到右依次为“搜索”、“我的设备”、“历史记录”、“消息”、“设置”。
搜索:可以搜索“文件夹”、“用户”以及“设备”的名称。
我的设备:当前设备的信息,在这里可以链接你的其他设备。
历史记录:参与人员的对分享文件的操作记录。
通知:相关的消息通知。
设置:软件的相关设置。
进阶技巧使用Shell脚本实现远程文件传输
进阶技巧使用Shell脚本实现远程文件传输Shell是一种通用的脚本语言,常用于自动化任务和批量处理。
使用Shell脚本可以方便地实现远程文件传输。
本文将介绍一些进阶技巧,帮助您更好地使用Shell脚本实现远程文件传输。
1. SSH密钥认证在进行远程文件传输之前,首先要建立安全的连接。
使用SSH密钥认证可以免去每次输入密码的麻烦,提高操作效率。
以下是使用SSH密钥认证的步骤:- 生成密钥对:在本地机器上使用`ssh-keygen`命令生成公钥和私钥。
- 将公钥传输到远程服务器:使用`ssh-copy-id`命令将生成的公钥传输到远程服务器上的`~/.ssh/authorized_keys`文件中。
- 测试连接:使用`ssh`命令测试连接,确认无需输入密码即可登录。
2. SCP命令传输文件SCP是Secure Copy的缩写,是基于SSH的安全文件传输协议。
通过SCP命令可以实现远程文件的传输。
- 上传文件:使用`scp`命令将本地文件上传至远程服务器。
示例命令:`scp localfile.txt user@remote:/path/to/destination`。
- 下载文件:使用`scp`命令将远程服务器上的文件下载到本地。
示例命令:`scp user@remote:/path/to/file.txt localfile.txt`。
3. SFTP协议传输文件SFTP是SSH File Transfer Protocol的缩写,通过SFTP协议可以在客户端和服务器之间传输文件。
可以使用`lftp`工具实现SFTP协议的文件传输。
- 进入SFTP交互模式:在终端中输入`lftpsftp://user:password@remote`命令,进入SFTP交互模式。
- 上传文件:在SFTP交互模式下,使用`put`命令将本地文件上传至远程服务器。
示例命令:`put localfile.txt`。
- 下载文件:在SFTP交互模式下,使用`get`命令将远程服务器上的文件下载到本地。
c语言课程设计优秀案例
c语言课程设计优秀案例C语言是一门广泛应用于计算机科学领域的编程语言,它具有高效、简洁、可移植等特点,因此在计算机科学领域中得到了广泛的应用。
在C语言课程设计中,学生需要通过实践来掌握C语言的基本语法和编程思想,同时也需要通过设计优秀的案例来提高自己的编程能力。
下面是10个优秀的C语言课程设计案例。
1. 学生成绩管理系统这个案例要求学生设计一个学生成绩管理系统,可以实现学生信息的录入、查询、修改和删除,同时还可以计算学生的平均成绩、最高成绩和最低成绩等统计信息。
2. 简单计算器这个案例要求学生设计一个简单的计算器,可以实现加、减、乘、除等基本运算,同时还可以实现括号、小数点和负数等高级运算。
3. 迷宫游戏这个案例要求学生设计一个迷宫游戏,可以实现玩家在迷宫中寻找出口的过程,同时还可以实现随机生成迷宫、计时和计分等功能。
4. 图书管理系统这个案例要求学生设计一个图书管理系统,可以实现图书信息的录入、查询、修改和删除,同时还可以实现借书和还书等功能。
5. 简单的文件管理器这个案例要求学生设计一个简单的文件管理器,可以实现文件的创建、删除、复制和移动等基本操作,同时还可以实现文件夹的创建和删除等高级操作。
6. 简单的网络聊天程序这个案例要求学生设计一个简单的网络聊天程序,可以实现用户之间的文字聊天和文件传输等功能,同时还可以实现用户登录和注册等操作。
7. 简单的音乐播放器这个案例要求学生设计一个简单的音乐播放器,可以实现音乐的播放、暂停、停止和跳转等基本操作,同时还可以实现音乐列表的管理和歌词显示等高级功能。
8. 简单的游戏开发这个案例要求学生设计一个简单的游戏,可以实现玩家的移动、攻击和防御等基本操作,同时还可以实现关卡设计和游戏难度调整等高级功能。
9. 简单的人工智能程序这个案例要求学生设计一个简单的人工智能程序,可以实现基本的语音识别、图像识别和自然语言处理等功能,同时还可以实现机器学习和深度学习等高级功能。
C#语言使用gRPC、proto...
C#语⾔使⽤gRPC、proto... 初识gRPC还是⼀位做JAVA的同事在项⽬中⽤到了它,为了C#的客户端程序和java的服务器程序进⾏通信和数据交换,当时还是对⽅编译成C#,我直接调⽤。
后来,⾃⼰下来做了C#版本gRPC编写,搜了很多资料,但许多都是从⼊门开始?调⽤说“Say Hi!”这种官⽅标准的⼊门⽰例,然后遇到各种问题…… 关于gRPC和Protobuf介绍,就不介绍了,⽹络上⼀搜⼀⼤把,随便⼀抓都是标准的官⽅,所以直接从使⽤说起。
protobuf的代码仓库:1、新建解决⽅案 分别在VS中新建解决⽅案:GrpcTest;再在解决⽅案中新建三个项⽬:GrpcClient、GrpcServer、GrpcService,对应的分别是客户端(wpf窗体程序)、服务端(控制台程序)、gRPC服务者(控制台程序)。
在GrpcClient和GrpcServer项⽬中添加对GrpcService的引⽤。
在VS中对3个项⽬添加⼯具包引⽤:右键点击“解决⽅案gRPCDemo”,点击“管理解决⽅案的NuGet程序包”,在浏览中分别搜索"Grpc"、"Grpc.Tools"、"Google.Protobuf",然后点击右⾯项⽬,全选,再点击安装(也可以⽤视图 -> 窗⼝ -> 程序包管理器控制台中的"Install-Package Grpc"进⾏这⼀步,这⾥不提供这种⽅法,有兴趣⾃⼰百度)。
2、proto⽂件的语法required:⼀个格式良好的消息⼀定要含有1个这种字段。
表⽰该值是必须要设置的。
optional:消息格式中该字段可以有0个或1个值(不超过1个)。
repeated:在⼀个格式良好的消息中,这种字段可以重复任意多次(包括0次)。
重复的值的顺序会被保留。
表⽰该值可以重复,相当于java中的List。
使用MFC实现点对点的文件传输
□“端口号”编辑控件(Edit Box)。用于确定通讯的端口号。所有属性均按照默认值既可。
先给大家简单介绍一下基本的思路。这个程序所采用的是基于TCP/IP协议的Winsock编程原理,相信如果对这方面的程序设计有所了解的人都应该知道对于这种编程模型一般都是采用客户机/服务器(Client/Server)方式,在这个程序里面也正是采用这种基本的方法。为了方便使用,我把客户机和服务器合而为一,但其实质还是一样的。
virtual ~CMessage();
public:
int m_nType;
CString m_strFileName;
DWORD m_dwFileSize;
};
其中,m_nType用于标识消息的类型;m_strFileName为文件的名称;m_dwFileSize为文件的大小。
为了方便使用,我对消息类的CMessage的构造函数进行了重载,CMessage()为默认的构造函数,如果只是发送一般的控制信息我们可以使用CMessage(int nType)构造函数,当需要发送文件名及大小的时候我们可以使用CMessage(int nType, CString strFileName, DWORD dwFileSize)构造函数,三个构造函数的源代码如下:
IDC_RECEIVE_SIZE 0 字节 显示已经发送或接受的文件尺寸
□先删除对话框中原有的确定按钮,然后再按照图1所示添加和修改按钮的属性,最终对话框中按钮的属性如下所示。
C上传文件到服务器(含接收端源码)
C上传⽂件到服务器(含接收端源码)实例向⼤家展⽰了如何⽤Visual C#实现⽹络⽂件的下载,使⽤Visual C#进⾏Internet通讯编程是⾮常⽅便的。
在上⾯的程序中,我们仅仅⽤到了WebClient类的⼀些⽅法,⽽WebClient类不光提供了⽹络⽂件下载的⽅法,还提供了⽂件上传的⽅法【实例简介】⼀.概述:本⽂通过⼀个实例向⼤家介绍⽤Visual C#进⾏Internet通讯编程的⼀些基本知识。
我们知道.Net类包含了请求/响应层、应⽤协议层、传输层等层次。
在本程序中,我们运⽤了位于请求/响应层的WebRequest类以及WebClient类等来实现⾼抽象程度的Internet通讯服务。
本程序的功能是完成⽹络⽂件的下载。
⼆.实现原理:程序实现的原理⽐较简单,主要⽤到了WebClient类和FileStream类。
其中WebClient类处于名字空间中,该类的主要功能是提供向URI标识的资源发送数据和从URI标识的资源接收数据的公共⽅法。
我们利⽤其中的DownloadFile()⽅法将⽹络⽂件下载到本地。
然后⽤FileStream类的实例对象以数据流的⽅式将⽂件数据写⼊本地⽂件。
这样就完成了⽹络⽂件的下载。
三.实现步骤:⾸先,打开Visual ,新建⼀个Visual C# Windows应⽤程序的⼯程,不妨命名为"MyGetCar"。
接着,布置主界⾯。
我们先往主窗体上添加如下控件:两个标签控件、两个⽂本框控件、⼀个按钮控件以及⼀个状态栏控件。
最终的主窗体如下图所⽰:完成主窗体的设计,我们接着完成代码的编写。
在理解了基本原理的基础上去完成代码的编写是相当容易。
程序中我们主要⽤到的是WebClient类,不过在我们调⽤WebClient类的实例对象前,我们需要⽤WebRequest类的对象发出对统⼀资源标识符(URI)的请求。
try{WebRequest myre=WebRequest.Create(URLAddress);}catch(WebException exp){MessageBox.Show(exp.Message,"Error");}这是⼀个try-catch语句,try块完成向URI的请求,catch块则捕捉可能的异常并显⽰异常信息。
中职计算机网络技术试题
中职计算机网络技术试题随着信息技术的飞速发展,计算机网络技术已成为中职教育中不可或缺的一门学科。
本篇文章将围绕中职计算机网络技术试题进行探讨,以帮助读者更好地理解计算机网络技术的相关知识。
答:计算机网络是指将多台计算机或设备通过通信线路和通信设备连接起来,实现数据传输和资源共享的系统。
答:网络协议是一套规则和标准,用于在计算机网络中实现数据传输和控制。
它规定了计算机之间通信的方式、数据格式、传输速率等。
答:IP是指互联网协议,是网络中每个主机所必须拥有的唯一。
它由四个0到255之间的数字组成,以点分十进制表示。
答:DNS是域名系统,它可以将域名解析为对应的IP,以便用户可以通过域名访问网站。
答:浏览器是一种用于访问万维网的软件。
它能够解析并显示HTML 页面,可以链接其他网页,还可以下载和播放网络上的视频、音频等多媒体内容。
答:电子邮件是一种通过网络发送和接收邮件的通信方式。
它使用SMTP、POP3等协议,可以在不同的计算机和设备之间传递邮件。
答:FTP是文件传输协议,用于在网络上传输文件。
它使用TCP协议,支持文本文件、二进制文件、图像文件等的传输。
答:远程登录是指用户通过本地计算机登录到远程服务器,以控制其操作。
它使用Telnet协议,可以在本地和远程之间进行交互式会话。
答:TCP是传输控制协议,是一种面向连接的协议。
它提供了可靠的数据传输服务,确保数据按照发送的顺序进行接收。
答:UDP是用户数据报协议,是一种无连接的协议。
它提供了不可靠的数据传输服务,不保证数据的顺序性和完整性。
答:路由器是一种连接不同网络的设备,能够将数据包从一个网络转发到另一个网络。
它可以根据路由表决定数据包的传输路径。
答:子网掩码是一种用于确定IP的网络和主机部分的标识符。
它由一串1和0组成,1表示网络部分,0表示主机部分。
答:防火墙是一种用于保护网络安全的设备或软件,能够限制外部网络对内部网络的访问权限。
它可以过滤进出的网络流量,阻止恶意攻击和非法访问。
