您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > C# TCP发送消息和传输文件
【背景】最近做了一个双机备份,就是服务器上有个文件夹,会接收客户端传来的文件,而我们要做的就是同步这台服务器和另一台备用服务器上的文件.为了实现这个功能我们使用的tcp点对点传输.【开发环境】VS2005【实现原理】要实现同步要解决两个问题,一个是获取本地服务器上上传上来的文件,二是实现两台机器间的文件传输.第一个问题我们用的FileSystemWatcher这个可以监视指定文件夹下的文件变动,然后我们把变动的文件信息记录到数据库,在指定的时间间隔后同步两台机器的文件.第二个问题我们用的tcp文件传输,我们按照一定的原则通过传输消息来告知备份服务器的要传输的文件名称和大小,然后传输文件.【代码】1:FileSystemWatcher监视文件变动的就不介绍了,很简单的winform控件应用.2:为了完成文件传输,我做了一个TcpHelper类库,其中包括TcpCommon,TcpClientHelper,TcpListenerHelper三个类,TcpCommon主要实现了文件传输时用的一些公共的方法比如发送接收文件,发送接收消息,和文件hash的计算TcpCommonusingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Security.Cryptography;usingSystem.IO;usingSystem.Net.Sockets;namespaceXpwy.Backup.PTcpHelper{internalclassTcpCommon{privatestaticreadonlyint_blockLength=500*1024;///summary///计算文件的hash值////summaryinternalstringCalcFileHash(stringFilePath){MD5CryptoServiceProvidermd5=newMD5CryptoServiceProvider();byte[]hash;using(FileStreamfs=newFileStream(FilePath,FileMode.Open,FileAccess.Read,FileShare.Read,4096)){hash=md5.ComputeHash(fs);}returnBitConverter.ToString(hash);}///summary///发送文件////summary///paramname=filePath/param///paramname=stream/param///returns/returnsinternalboolSendFile(stringfilePath,NetworkStreamstream){FileStreamfs=File.Open(filePath,FileMode.Open);intreadLength=0;byte[]data=newbyte[_blockLength];//发送大小byte[]length=newbyte[8];BitConverter.GetBytes(newFileInfo(filePath).Length).CopyTo(length,0);stream.Write(length,0,8);//发送文件while((readLength=fs.Read(data,0,_blockLength))0){stream.Write(data,0,readLength);}fs.Close();returntrue;}///summary///接收文件////summary///paramname=filePath/param///paramname=stream/param///returns/returnsinternalboolReceiveFile(stringfilePath,NetworkStreamstream){try{longcount=GetSize(stream);if(count==0){returnfalse;}longindex=0;byte[]clientData=newbyte[_blockLength];if(File.Exists(filePath)){File.Delete(filePath);}stringpath=newFileInfo(filePath).Directory.FullName;if(!Directory.Exists(path)){Directory.CreateDirectory(path);}FileStreamfs=File.Open(filePath,FileMode.OpenOrCreate);try{//计算当前要读取的块的大小intcurrentBlockLength=0;if(_blockLengthcount-index){currentBlockLength=_blockLength;}else{currentBlockLength=(int)(count-index);}intreceivedBytesLen=stream.Read(clientData,0,currentBlockLength);index+=receivedBytesLen;fs.Write(clientData,0,receivedBytesLen);while(receivedBytesLen0&&indexcount){clientData=newbyte[_blockLength];receivedBytesLen=0;if(_blockLengthcount-index){currentBlockLength=_blockLength;}else{currentBlockLength=(int)(count-index);}receivedBytesLen=stream.Read(clientData,0,currentBlockLength);index+=receivedBytesLen;fs.Write(clientData,0,receivedBytesLen);}}catch(Exceptionex){returnfalse;}finally{fs.Close();}}catch(Exceptionex){returnfalse;}returntrue;}///summary///发送消息////summary///paramname=message/param///paramname=stream/param///returns/returnsinternalboolSendMessage(stringmessage,NetworkStreamstream){byte[]data=Encoding.UTF8.GetBytes(message);byte[]resultData=newbyte[8+data.Length];BitConverter.GetBytes(data.Length).CopyTo(resultData,0);data.CopyTo(resultData,8);stream.Write(resultData,0,resultData.Length);returntrue;}///summary///读取消息////summary///paramname=stream/param///returns/returnsinternalstringReadMessage(NetworkStreamstream){stringresult=;intmessageLength=0;byte[]resultbyte=newbyte[500*1024];//读取数据大小intindex=0;intcount=GetSize(stream);byte[]data=newbyte[count];while(indexcount&&(messageLength=stream.Read(data,0,count-index))!=0){data.CopyTo(resultbyte,index);index+=messageLength;}result=Encoding.UTF8.GetString(resultbyte,0,index);returnresult;}///summary///获取要读取的数据的大小////summary///paramname=stream/param///returns/returnsprivateintGetSize(NetworkStreamstream){intcount=0;byte[]countBytes=newbyte[8];try{if(stream.Read(countBytes,0,8)==8){count=BitConverter.ToInt32(countBytes,0);}else{return0;}}catch(Exceptionex){}returncount;}}}TcpClientHelperusingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Net.Sockets;namespaceXpwy.Backup.PTcpHelper{publicclassTcpClientHelper:IDisposable{TcpClientclient;NetworkStreamnetstream;string_serverip=127.0.0.1;int_port=8080;TcpCommontcpCommon=newTcpCommon();#regionTcpClientHelperconstructorpublicTcpClientHelper(stringstrServerIP,intserverPort){_serverip=strServerIP;_port=serverPort;}#endregionpublicvoidStart(){client=newTcpClient(_serverip,_port);netstream=client.GetStream();}publicvoidStop(){if(netstream!=null){netstream.Close();}if(client!=null){client.Close();}}#regionTcpCommon所有方法publicstringCalcFileHash(stringFilePath){returntcpCommon.CalcFileHash(FilePath);}publicboolSendFile(stringfilePath){returntcpCommon.SendFile(filePath,netstream);}publicboolReceiveFile(stringfilePath){returntcpCommon.ReceiveFile(filePath,netstream);}publicboolSendMessage(stringmessage){returntcpCommon.SendMessage(message,netstream);}publicstringReadMessage(){returntcpCommon.ReadMessage(netstream);}#endregion#regionIDisposable成员publicvoidDispose(){if(netstream!=null){netstream.Close();}if(client!=nu
本文标题:C# TCP发送消息和传输文件
链接地址:https://www.777doc.com/doc-4005331 .html