首页 使用C#进行点对点通讯和文件传输

使用C#进行点对点通讯和文件传输

举报
开通vip

使用C#进行点对点通讯和文件传输使用C#进行点对点通讯和文件传输第1页 使用C#进行点对点通讯和文件传输 程序分三部分,包括发送部分、接受部分和一个两者共享的通讯基类,这个基类才是俺心血的结晶:)一、通讯基类 using System; using System.Net.Sockets; using System.Net ; using System.IO ; using System.Windows.Forms; using System.Text; namespace BaseClass { /// 传送信息的格式为给...

使用C#进行点对点通讯和文件传输
使用C#进行点对点通讯和文件传输第1页 使用C#进行点对点通讯和文件传输 程序分三部分,包括发送部分、接受部分和一个两者共享的通讯基类,这个基类才是俺心血的结晶:)一、通讯基类 using System; using System.Net.Sockets; using System.Net ; using System.IO ; using System.Windows.Forms; using System.Text; namespace BaseClass { /// 传送信息的格式为给定长度的命令部分+给定长度的命令注释部分+可变长度的长度信息+可变长度的信息部分 public class CommunClass { public CommunClass() { // TODO: 在此处添加构造函数逻辑 } /// 命令部分的长度 private static readonly int CMDLEN = 50 ; /// 命令注释部分的长度 private static readonly int DESCLEN = 100 ; /// 可变长度的长度信息部分所占的字节数 private static readonly int DYNAMICLENGTHLEN = 10 ; /// 每次处理可变信息部分的长度 private static readonly int DEALLEN = 1024 ; /// /应答的最大长度 private static readonly int RESPONLEN = 20 ; /// 用于填充命令或注释不足长度部分的字符 private static readonly char FILLCHAR = ''^'' ; /// 成功发送一部分数据后的回调 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 (也可以认为是触发的事件,但严格来说还不是) public delegate void OnSend(int iTotal,int iSending) ; /// 根据给定的服务器和端口号建立连接 /// 服务器名 /// 端口号 public static Socket ConnectToServer(string strHost,int iPort) { try { IPAddress ipAddress = Dns.Resolve(strHost).AddressList[0]; IPEndPoint ipPoint = new IPEndPoint(ipAddress,iPort) ; Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp) ; s.Connect(ipPoint) ; return s ; } catch (Exception e) { throw (new Exception("建立到服务器的连接出错" + e.Message)) ; } } /// 将文本写到Socket中 /// 要发送信息的Socket /// 要发送的信息 /// 是否成功 public static bool WriteTextToSocket(Socket s,string strInfo) { byte [] buf = Encoding.UTF8.GetBytes(strInfo) ; try { s.Send(buf,0,buf.Length,SocketFlags.None) ; return true ; } catch(Exception err) { MessageBox.Show("发送文本失败!"+err.Message) ; return false ; } } /// 将命令文本写到Socket中 /// 要发送命令文本的Socket /// 要发送的命令文本 // 是否成功 public static bool WriteCommandToSocket(Socket s,string strCmd) { if (strCmd == "") strCmd = "NOP" ; strCmd = strCmd.PadRight(CMDLEN,FILLCHAR) ; return WriteTextToSocket(s,strCmd) ; } /// /// 将命令注释写到Socket中 /// /// 要发送命令注释的Socket /// 要发送的命令注释 /// 是否成功 public static bool WriteCommandDescToSocket(Socket s,string strDesc) { if (strDesc == "") strDesc = "0" ; strDesc = strDesc.PadRight(DESCLEN,FILLCHAR) ; return WriteTextToSocket(s,strDesc) ; } /// 发送可变信息的字节数 /// 要发送字节数的Socket /// 字节数 /// 是否成功 public static bool WriteDynamicLenToSocket(Socket s,int iLen) { string strLen = iLen.ToString().PadRight(DYNAMICLENGTHLEN,FILLCHAR) ; return WriteTextToSocket(s,strLen) ; } /// 将缓存的指定部分发送到Socket /// 要发送缓存的Socket /// 要发送的缓存 /// 要发送缓存的起始位置 /// 要发送缓存的字节数 /// 每次发送的字节说 /// 每次发送成功后的回调函数 /// 是否发送成功 public static bool WriteBufToSocket(Socket s,byte [] buf,int iStart,int iCount,int iBlock,OnSend SendSuccess) { int iSended = 0 ; int iSending = 0 ; while(iSended { if (iSended + iBlock iSending = iBlock ; else iSending = iCount - iSended ; s.Send(buf,iStart+iSended,iSending,SocketFlags.None) ; iSended += iSending ; if (ReadResponsionFromSocket(s)=="OK") if (SendSuccess != null) SendSuccess(iCount,iSended) ; else return false; } return true ; } /// 将长度不固定文本发送到socket /// 要发送文本的Socket /// 要发送的文本 /// 成功发送一部分文本后的回调函数 /// 得到文本长度的回调函数 public static bool WriteDynamicTextToSocket(Socket s,string strText, OnSend OnSendText) { byte [] buf = Encoding.UTF8.GetBytes(strText) ; int iLen = buf.Length ; try { WriteDynamicLenToSocket(s,iLen) ; return WriteBufToSocket(s,buf,0,iLen,DEALLEN,OnSendText) ; } catch(Exception err) { MessageBox.Show("发送文本失败!"+err.Message) ; return false ; } } /// 将文件写到Socket /// 要发送文件的Socket /// 要发送的文件 /// 是否成功 public static bool WriteFileToSocket(Socket s,string strFile, OnSend OnSendFile) { FileStream fs = new FileStream(strFile,FileMode.Open,FileAccess.Read,FileShare.Read) ; int iLen = (int)fs.Length ; WriteDynamicLenToSocket(s,iLen) ; byte [] buf = new byte[iLen] ; try { fs.Read(buf,0,iLen) ; return WriteBufToSocket(s,buf,0,iLen,DEALLEN,OnSendFile) ; } catch(Exception err) { MessageBox.Show("发送文件失败!"+err.Message) ; return false ; } finally { fs.Close() ; } } /// 对方对自己消息的简单回应 public static string ReadResponsionFromSocket( Socket s) { byte [] bufCmd = new byte[RESPONLEN] ; int iCount = s.Receive(bufCmd) ; string strRespon = Encoding.UTF8.GetString(bufCmd,0,iCount) ; return strRespon ; } /// 从Socket读取命令 /// 要读取命令的Socket /// 读取的命令 public static string ReadCommandFromSocket( Socket s) { byte [] bufCmd = new byte[CMDLEN] ; int iCount = s.Receive(bufCmd,0,CMDLEN,SocketFlags.Partial) ; string strCommand = Encoding.UTF8.GetString(bufCmd,0,CMDLEN) ; return strCommand = strCommand.TrimEnd(FILLCHAR) ; } /// 读取命令注释 /// 要读取命令注释的Socket /// 读取的命令注释 public static string ReadCommandDescFromSocket( Socket s) { byte [] bufCmd = new byte[DESCLEN] ; int iCount = s.Receive(bufCmd,0,DESCLEN,SocketFlags.Partial) ; string strCommand = Encoding.UTF8.GetString(bufCmd,0,DESCLEN) ; return strCommand = strCommand.TrimEnd(FILLCHAR) ; } /// 读取可变部分的长度 // 要读取可变部分长度的Socket /// 读取的可变部分的长度 public static int ReadDynamicLenFromSocket( Socket s) { byte [] bufCmd = new byte[DYNAMICLENGTHLEN] ; int iCount = s.Receive(bufCmd,0,DYNAMICLENGTHLEN,SocketFlags.Partial) ; string strCommand = Encoding.UTF8.GetString(bufCmd,0,DYNAMICLENGTHLEN) ; return int.Parse(strCommand.TrimEnd(FILLCHAR)) ; } /// 读取文本形式的可变信息 /// 要读取可变信息的Socket /// 读取的可变信息 public static string ReadDynamicTextFromSocket( Socket s) { int iLen = ReadDynamicLenFromSocket(s) ; byte [] buf = new byte[iLen] ; string strInfo = "" ; int iReceiveded = 0 ; int iReceiveing = 0 ; while(iReceiveded { if (iReceiveded + DEALLEN iReceiveing = DEALLEN ; else iReceiveing = iLen - iReceiveded ; s.Receive(buf,iReceiveded,iReceiveing,SocketFlags.None) ; CommunClass.WriteTextToSocket(s,"OK") ; iReceiveded+= iReceiveing ; } strInfo = Encoding.UTF8.GetString(buf,0,iLen) ; return strInfo ; } /// /// 读取文件形式的可变信息 /// /// 要读取可变信息的Socket /// 读出后的文件保存位置 /// 是否读取成功 public static bool ReadDynamicFileFromSocket( Socket s,string strFile) { int iLen = ReadDynamicLenFromSocket(s) ; byte [] buf = new byte[iLen] ; FileStream fs = new FileStream(strFile,FileMode.Create,FileAccess.Write) ; try { int iReceiveded = 0 ; int iReceiveing = 0 ; while(iReceiveded { if (iReceiveded + DEALLEN iReceiveing = DEALLEN ; else iReceiveing = iLen - iReceiveded ; s.Receive(buf,iReceiveded,iReceiveing,SocketFlags.None) ; CommunClass.WriteTextToSocket(s,"OK") ; iReceiveded+= iReceiveing ; } fs.Write(buf,0,iLen) ; return true ; } catch(Exception err) { MessageBox.Show("接收文件失败"+err.Message) ; return false ; } finally { fs.Close() ; } } }//end class }//end namespace 上面是俺的通讯基础类,有了这个类,再进行发送接受还不是小菜一碟吗? 上面介绍了通讯的基类,下面就是使用那个类进行发送和接收的部分: 二、发送部分: 发送咱们使用了多线程,可以同时进行多个任务,比如发送文件、发送文本等,互不影响:发送文本方法: private void StartSendText(string strHost,int iPort,string strInfo) { SendText stText = new SendText(strHost,iPort,strInfo,new CommunClass.OnSend(OnSendDrawProgress)) ; StartThread(new ThreadStart(stText.Send)) ; } 下面是他调用用到的一些方法: 开始一个线程 private void StartThread(ThreadStart target) { Thread doStep = new Thread(target) ; doStep.IsBackground = true ; doStep.Start() ; } 发送一部分(本文设置的是1024字节)成功后的回调方法 public void OnSendDrawProgress(int iTotal,int iSending) { if (iTotal != pbMain.Maximum) pbMain.Maximum = iTotal ; pbMain.V alue = iSending ; } 因为使用的是线程,所以发送文本使用的是一个发送文本类的方法,该类如下: public class SendText { private string Host ; private int Port ; private string Info ; private CommunClass.OnSend onsend ; public SendText(string strHost,int iPort,string strInfo, CommunClass.OnSend onSend) { Host = strHost ; Port = iPort ; Info = strInfo ; onsend = onSend ; } public void Send() { Socket s = null ; try { s = CommunClass.ConnectToServer(Host,Port) ; CommunClass.WriteCommandToSocket(s,"SENDTEXT") ; CommunClass.WriteCommandDescToSocket(s,"") ; CommunClass.WriteDynamicTextToSocket(s,Info,onsend) ; } catch (Exception e) { MessageBox.Show(e.Message) ; } finally { if (s != null) s.Close() ; } } }//end class 这样就可以使用一个线程发送文本了。 发送文件的方法也类似: private void StartSendFile(string strHost,int iPort,string strFile) { SendFile sfFile = new SendFile(strHost,iPort,strFile,this.pbMain) ; pbMain.V alue = 0 ; StartThread(new ThreadStart(sfFile.Send)) ; } 发送文件的类: public class SendFile { private string Host ; private int Port ; private string FileToSend ; private ProgressBar pbar; public SendFile(string strHost,int iPort,string strFile,ProgressBar pbMain) { Host = strHost ; Port = iPort ; FileToSend = strFile ; pbar = pbMain ; } public void Send() { Socket s = null ; try { s = CommunClass.ConnectToServer(Host,Port) ; CommunClass.WriteCommandToSocket(s,"SENDFILE") ; CommunClass.WriteCommandDescToSocket(s,"") ; CommunClass.WriteFileToSocket(s,FileToSend,new CommunClass.OnSend(OnSendDrawProgress)) ; } catch (Exception e) { MessageBox.Show(e.Message) ; } finally { if (s != null) s.Close() ; } } public void OnSendDrawProgress(int iTotal,int iSending) { if (iTotal != pbar.Maximum) pbar.Maximum = iTotal ; pbar.V alue = iSending ; } }//end class 当然,你发送一个命令让服务器端启动一个程序(靠,这不成木马了吗?)也可以:俺这里只给出一部分代码,其余的您自己可以发挥以下: public class ExeCuteFile { private string Host ; private int Port ; private string FileName ; private string cmdParam ; public ExeCuteFile(string strHost,int iPort,string strFileName,string strCmdParam) { Host = strHost ; Port = iPort ; FileName = strFileName ; cmdParam = strCmdParam ; } public void Send() { Socket s = null ; try { s = CommunClass.ConnectToServer(Host,Port) ; CommunClass.WriteCommandToSocket(s,"EXECUTEFILE") ; CommunClass.WriteCommandDescToSocket(s,FileName) ; CommunClass.WriteDynamicTextToSocket(s,"",null) ; MessageBox.Show(CommunClass.ReadDynamicTextFromSocket(s)) ; } catch (Exception e) { MessageBox.Show(e.Message) ; } finally { if (s != null) s.Close() ; } } } 三、下面是服务器端接受信息的代码: 创建监听: /// 再给定的主机和端口上创建监听程序 private void BuildingServer(string strAddress,int iPort) { IPAddress ipAddress = Dns.Resolve(strAddress).AddressList[0]; try { listener = new TcpListener(ipAddress, iPort); } catch ( Exception e) { AddInfo(e.Message) ; } } /// 开始监听 private void StartListen() { bool done = false; listener.Start(); while (!done) { Socket s = listener.AcceptSocket() ; if(s != null) { DealWithSocket dws = new DealWithSocket(s,this.tbLog) ; StartThread(new ThreadStart(dws.DealWith)) ; } } } private void StartThread(ThreadStart target) { Thread doStep = new Thread(target) ; doStep.IsBackground = true ; doStep.Start() ; } 开始监听后,对于每一个监听到的客户端的连接都用一个单独的线程来处理,处理通过类DealWithSocket 来完成,下面是类代码: public class DealWithSocket { private Socket s = null ; private TextBox tbLog = null ; public DealWithSocket(Socket newSocket,TextBox tbInfo) { s = newSocket ; tbLog = tbInfo ; } public void DealWith() { string strCmd = CommunClass.ReadCommandFromSocket(s) ; string strDesc = CommunClass.ReadCommandDescFromSocket(s) ; AddInfo(strCmd) ; switch(strCmd) { case"SENDFILE" : CommunClass.ReadDynamicFileFromSocket(s,"e:\\rrr.txt") ; break ; case"EXECUTEFILE" : string strParam = CommunClass.ReadDynamicTextFromSocket(s) ; string strResult = ExeCuteFile(strDesc,strParam) ; CommunClass.WriteDynamicTextToSocket(s,strResult,null) ; 使用C#进行点对点通讯和文件传输第11页 break ; default: string strDetail = CommunClass.ReadDynamicTextFromSocket(s) ; AddInfo(strDetail) ; break ; } try { s.Close() ; } catch (Exception e) { AddInfo(e.Message) ; } } private void AddInfo(string strInfo) { string Info = DateTime.Now.ToLongTimeString() + " "+ strInfo +"\r\n" ; tbLog.Text += Info ; tbLog.Refresh() ; } private string ExeCuteFile(string strFileName,string strCmdParam) { System.Diagnostics.Process proc = new System.Diagnostics.Process() ; proc.StartInfo.FileName = strFileName ; proc.StartInfo.Arguments = strCmdParam ; try { proc.Start() ; return"OK" ; } catch(Exception err) { return err.Message ; } } }//end class
本文档为【使用C#进行点对点通讯和文件传输】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_574951
暂无简介~
格式:doc
大小:56KB
软件:Word
页数:0
分类:互联网
上传时间:2019-08-27
浏览量:13