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

最近一个项目要用到点对点文件传输,俺就到处找资料写程序,最后终于完成了,为了让别人少走些弯路,俺决定将俺程序中最重要的部分贡献出来,希望对大家有所帮助。



俺的程序分三部分,包括发送部分、接受部分和一个两者共享的通讯基类,这个基类才是俺心血的结晶:)

  1. 一、通讯基类  
  2.  
  3. using System;  
  4.  
  5. using System.Net.Sockets;  
  6.  
  7. using System.Net ;  
  8.  
  9. using System.IO ;  
  10.  
  11. using System.Windows.Forms;  
  12.  
  13. using System.Text;  
  14.  
  15.  
  16.  
  17. namespace BaseClass  
  18.  
  19. {  
  20.  
  21. /// <summary>  
  22.  
  23. /// 传送信息的格式为 给定长度的命令部分+给定长度的命令注释部分+可变长度的长度信息+可变长度的信息部分  
  24.  
  25. /// </summary>  
  26.  
  27. public class CommunClass  
  28.  
  29. {  
  30.  
  31. public CommunClass()  
  32.  
  33. {  
  34.  
  35. //  
  36.  
  37. // TODO: 在此处添加构造函数逻辑  
  38.  
  39. //  
  40.  
  41. }  
  42.  
  43. /// <summary>  
  44.  
  45. /// 命令部分的长度  
  46.  
  47. /// </summary>  
  48.  
  49. private static readonly int CMDLEN = 50 ;  
  50.  
  51. /// <summary>  
  52.  
  53. /// 命令注释部分的长度  
  54.  
  55. /// </summary>  
  56.  
  57. private static readonly int DESCLEN = 100 ;  
  58.  
  59. /// <summary>  
  60.  
  61. /// 可变长度的长度信息部分所占的字节数  
  62.  
  63. /// </summary>  
  64.  
  65. private static readonly int DYNAMICLENGTHLEN = 10 ;  
  66.  
  67. /// <summary>  
  68.  
  69. /// 每次处理可变信息部分的长度  
  70.  
  71. /// </summary>  
  72.  
  73. private static readonly int DEALLEN = 1024 ;  
  74.  
  75. /// <summary>  
  76.  
  77. /// /应答的最大长度  
  78.  
  79. /// </summary>  
  80.  
  81. private static readonly int RESPONLEN = 20 ;  
  82.  
  83. /// <summary>  
  84.  
  85. /// 用于填充命令或注释不足长度部分的字符  
  86.  
  87. /// </summary>  
  88.  
  89. private static readonly char FILLCHAR = ''^'' ;  
  90.  
  91.  
  92.  
  93. /// <summary>  
  94.  
  95. /// 成功发送一部分数据后的回调方法(也可以认为是触发的事件,但严格来说还不是)  
  96.  
  97. /// </summary>  
  98.  
  99. public delegate void OnSend(int iTotal,int iSending) ;  
  100.  
  101.  
  102.  
  103. /// <summary>  
  104.  
  105. /// 根据给定的服务器和端口号建立连接  
  106.  
  107. /// </summary>  
  108.  
  109. /// <param name="strHost">服务器名</param>  
  110.  
  111. /// <param name="iPort">端口号</param>  
  112.  
  113. /// <returns></returns>  
  114.  
  115. public static Socket ConnectToServer(string strHost,int iPort)  
  116.  
  117. {  
  118.  
  119. try  
  120.  
  121. {  
  122.  
  123. IPAddress ipAddress = Dns.Resolve(strHost).AddressList[0];  
  124.  
  125. IPEndPoint ipPoint = new IPEndPoint(ipAddress,iPort) ;  
  126.  
  127.  
  128.  
  129. Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp) ;  
  130.  
  131. s.Connect(ipPoint) ;  
  132.  
  133. return s ;  
  134.  
  135. }  
  136.  
  137. catch (Exception e)  
  138.  
  139. {  
  140.  
  141. throw (new Exception("建立到服务器的连接出错" + e.Message)) ;  
  142.  
  143. }  
  144.  
  145. }  
  146.  
  147. /// <summary>  
  148.  
  149. /// 将文本写到Socket中  
  150.  
  151. /// </summary>  
  152.  
  153. /// <param name="s">要发送信息的Socket</param>  
  154.  
  155. /// <param name="strInfo">要发送的信息</param>  
  156.  
  157. /// <returns>是否成功</returns>  
  158.  
  159. public static bool WriteTextToSocket(Socket s,string strInfo)  
  160.  
  161. {  
  162.  
  163. byte [] buf = Encoding.UTF8.GetBytes(strInfo) ;  
  164.  
  165. try  
  166.  
  167. {  
  168.  
  169. s.Send(buf,0,buf.Length,SocketFlags.None) ;  
  170.  
  171. return true ;  
  172.  
  173. }  
  174.  
  175. catch(Exception err)  
  176.  
  177. {  
  178.  
  179. MessageBox.Show("发送文本失败!"+err.Message) ;  
  180.  
  181. return false ;  
  182.  
  183. }  
  184.  
  185. }  
  186.  
  187. /// <summary>  
  188.  
  189. /// 将命令文本写到Socket中  
  190.  
  191. /// </summary>  
  192.  
  193. /// <param name="s">要发送命令文本的Socket</param>  
  194.  
  195. /// <param name="strInfo">要发送的命令文本</param>  
  196.  
  197. /// <returns>是否成功</returns>  
  198.  
  199. public static bool WriteCommandToSocket(Socket s,string strCmd)  
  200.  
  201. {  
  202.  
  203. if (strCmd == "")  
  204.  
  205. strCmd = "NOP" ;  
  206.  
  207. strCmd = strCmd.PadRight(CMDLEN,FILLCHAR) ;  
  208.  
  209. return WriteTextToSocket(s,strCmd) ;  
  210.  
  211. }  
  212.  
  213. /// <summary>  
  214.  
  215. /// 将命令注释写到Socket中  
  216.  
  217. /// </summary>  
  218.  
  219. /// <param name="s">要发送命令注释的Socket</param>  
  220.  
  221. /// <param name="strInfo">要发送的命令注释</param>  
  222.  
  223. /// <returns>是否成功</returns>  
  224.  
  225. public static bool WriteCommandDescToSocket(Socket s,string strDesc)  
  226.  
  227. {  
  228.  
  229. if (strDesc == "")  
  230.  
  231. strDesc = "0" ;  
  232.  
  233. strDesc = strDesc.PadRight(DESCLEN,FILLCHAR) ;  
  234.  
  235. return WriteTextToSocket(s,strDesc) ;  
  236.  
  237. }  
  238.  
  239. /// <summary>  
  240.  
  241. /// 发送可变信息的字节数  
  242.  
  243. /// </summary>  
  244.  
  245. /// <param name="s">要发送字节数的Socket</param>  
  246.  
  247. /// <param name="iLen">字节数</param>  
  248.  
  249. /// <returns>是否成功</returns>  
  250.  
  251. public static bool WriteDynamicLenToSocket(Socket s,int iLen)  
  252.  
  253. {  
  254.  
  255. string strLen = iLen.ToString().PadRight(DYNAMICLENGTHLEN,FILLCHAR) ;  
  256.  
  257. return WriteTextToSocket(s,strLen) ;  
  258.  
  259. }  
  260.  
  261. /// <summary>  
  262.  
  263. /// 将缓存的指定部分发送到Socket  
  264.  
  265. /// </summary>  
  266.  
  267. /// <param name="s">要发送缓存的Socket</param>  
  268.  
  269. /// <param name="buf">要发送的缓存</param>  
  270.  
  271. /// <param name="iStart">要发送缓存的起始位置</param>  
  272.  
  273. /// <param name="iCount">要发送缓存的字节数</param>  
  274.  
  275. /// <param name="iBlock">每次发送的字节说</param>  
  276.  
  277. /// <param name="SendSuccess">每次发送成功后的回调函数</param>  
  278.  
  279. /// <returns>是否发送成功</returns>  
  280.  
  281. public static bool WriteBufToSocket(Socket s,byte [] buf,int iStart,int iCount,int iBlock,OnSend SendSuccess)  
  282.  
  283. {  
  284.  
  285. int iSended = 0 ;  
  286.  
  287. int iSending = 0 ;  
  288.  
  289. while(iSended<iCount)  
  290.  
  291. {  
  292.  
  293. if (iSended + iBlock <= iCount)  
  294.  
  295. iSending = iBlock ;  
  296.  
  297. else  
  298.  
  299. iSending = iCount - iSended ;  
  300.  
  301. s.Send(buf,iStart+iSended,iSending,SocketFlags.None) ;  
  302.  
  303. iSended += iSending ;  
  304.  
  305. if (ReadResponsionFromSocket(s)=="OK")  
  306.  
  307. if (SendSuccess != null)  
  308.  
  309. SendSuccess(iCount,iSended) ;  
  310.  
  311. else  
  312.  
  313. return false;  
  314.  
  315. }  
  316.  
  317. return true ;  
  318.  
  319. }  
  320.  
  321. /// <summary>  
  322.  
  323. /// 将长度不固定文本发送到socket  
  324.  
  325. /// </summary>  
  326.  
  327. /// <param name="s">要发送文本的Socket</param>  
  328.  
  329. /// <param name="strText">要发送的文本</param>  
  330.  
  331. /// <param name="OnSendText">成功发送一部分文本后的回调函数</param>  
  332.  
  333. /// <param name="settextlen">得到文本长度的回调函数</param>  
  334.  
  335. /// <returns></returns>  
  336.  
  337. public static bool WriteDynamicTextToSocket(Socket s,string strText,  
  338.  
  339. OnSend OnSendText)  
  340.  
  341. {  
  342.  
  343. byte [] buf = Encoding.UTF8.GetBytes(strText) ;  
  344.  
  345.  
  346.  
  347. int iLen = buf.Length ;  
  348.  
  349. try  
  350.  
  351. {  
  352.  
  353. WriteDynamicLenToSocket(s,iLen) ;  
  354.  
  355. return WriteBufToSocket(s,buf,0,iLen,DEALLEN,OnSendText) ;  
  356.  
  357. }  
  358.  
  359. catch(Exception err)  
  360.  
  361. {  
  362.  
  363. MessageBox.Show("发送文本失败!"+err.Message) ;  
  364.  
  365. return false ;  
  366.  
  367. }  
  368.  
  369. }  
  370.  
  371. /// <summary>  
  372.  
  373. /// 将文件写到Socket  
  374.  
  375. /// </summary>  
  376.  
  377. /// <param name="s">要发送文件的Socket</param>  
  378.  
  379. /// <param name="strFile">要发送的文件</param>  
  380.  
  381. /// <returns>是否成功</returns>  
  382.  
  383. public static bool WriteFileToSocket(Socket s,string strFile,  
  384.  
  385. OnSend OnSendFile)  
  386.  
  387. {  
  388.  
  389. FileStream fs = new FileStream(strFile,FileMode.Open,FileAccess.Read,FileShare.Read) ;  
  390.  
  391. int iLen = (int)fs.Length ;  
  392.  
  393. WriteDynamicLenToSocket(s,iLen) ;  
  394.  
  395. byte [] buf = new byte[iLen] ;  
  396.  
  397. try  
  398.  
  399. {  
  400.  
  401. fs.Read(buf,0,iLen) ;  
  402.  
  403. return WriteBufToSocket(s,buf,0,iLen,DEALLEN,OnSendFile) ;  
  404.  
  405. }  
  406.  
  407. catch(Exception err)  
  408.  
  409. {  
  410.  
  411. MessageBox.Show("发送文件失败!"+err.Message) ;  
  412.  
  413. return false ;  
  414.  
  415. }  
  416.  
  417. finally  
  418.  
  419. {  
  420.  
  421. fs.Close() ;  
  422.  
  423. }  
  424.  
  425. }  
  426.  
  427. /// <summary>  
  428.  
  429. /// 对方对自己消息的简单回应  
  430.  
  431. /// </summary>  
  432.  
  433. /// <param name="s"></param>  
  434.  
  435. /// <returns></returns>  
  436.  
  437. public static string ReadResponsionFromSocket( Socket s)  
  438.  
  439. {  
  440.  
  441. byte [] bufCmd = new byte[RESPONLEN] ;  
  442.  
  443. int iCount = s.Receive(bufCmd) ;  
  444.  
  445. string strRespon = Encoding.UTF8.GetString(bufCmd,0,iCount) ;  
  446.  
  447. return strRespon ;  
  448.  
  449. }  
  450.  
  451. /// <summary>  
  452.  
  453. /// 从Socket读取命令  
  454.  
  455. /// </summary>  
  456.  
  457. /// <param name="s">要读取命令的Socket</param>  
  458.  
  459. /// <returns>读取的命令</returns>  
  460.  
  461. public static string ReadCommandFromSocket( Socket s)  
  462.  
  463. {  
  464.  
  465. byte [] bufCmd = new byte[CMDLEN] ;  
  466.  
  467. int iCount = s.Receive(bufCmd,0,CMDLEN,SocketFlags.Partial) ;  
  468.  
  469. string strCommand = Encoding.UTF8.GetString(bufCmd,0,CMDLEN) ;  
  470.  
  471. return strCommand = strCommand.TrimEnd(FILLCHAR) ;  
  472.  
  473. }  
  474.  
  475. /// <summary>  
  476.  
  477. /// 读取命令注释  
  478.  
  479. /// </summary>  
  480.  
  481. /// <param name="s">要读取命令注释的Socket</param>  
  482.  
  483. /// <returns>读取的命令注释</returns>  
  484.  
  485. public static string ReadCommandDescFromSocket( Socket s)  
  486.  
  487. {  
  488.  
  489. byte [] bufCmd = new byte[DESCLEN] ;  
  490.  
  491. int iCount = s.Receive(bufCmd,0,DESCLEN,SocketFlags.Partial) ;  
  492.  
  493. string strCommand = Encoding.UTF8.GetString(bufCmd,0,DESCLEN) ;  
  494.  
  495. return strCommand = strCommand.TrimEnd(FILLCHAR) ;  
  496.  
  497. }  
  498.  
  499. /// <summary>  
  500.  
  501. /// 读取可变部分的长度  
  502.  
  503. /// </summary>  
  504.  
  505. /// <param name="s">要读取可变部分长度的Socket</param>  
  506.  
  507. /// <returns>读取的可变部分的长度</returns>  
  508.  
  509. public static int ReadDynamicLenFromSocket( Socket s)  
  510.  
  511. {  
  512.  
  513. byte [] bufCmd = new byte[DYNAMICLENGTHLEN] ;  
  514.  
  515. int iCount = s.Receive(bufCmd,0,DYNAMICLENGTHLEN,SocketFlags.Partial) ;  
  516.  
  517. string strCommand = Encoding.UTF8.GetString(bufCmd,0,DYNAMICLENGTHLEN) ;  
  518.  
  519. return int.Parse(strCommand.TrimEnd(FILLCHAR)) ;  
  520.  
  521. }  
  522.  
  523. /// <summary>  
  524.  
  525. /// 读取文本形式的可变信息  
  526.  
  527. /// </summary>  
  528.  
  529. /// <param name="s">要读取可变信息的Socket</param>  
  530.  
  531. /// <returns>读取的可变信息</returns>  
  532.  
  533. public static string ReadDynamicTextFromSocket( Socket s)  
  534.  
  535. {  
  536.  
  537. int iLen = ReadDynamicLenFromSocket(s) ;  
  538.  
  539.  
  540.  
  541. byte [] buf = new byte[iLen] ;  
  542.  
  543. string strInfo = "" ;  
  544.  
  545.  
  546.  
  547. int iReceiveded = 0 ;  
  548.  
  549. int iReceiveing = 0 ;  
  550.  
  551. while(iReceiveded<iLen)  
  552.  
  553. {  
  554.  
  555. if (iReceiveded + DEALLEN <= iLen)  
  556.  
  557. iReceiveing = DEALLEN ;  
  558.  
  559. else  
  560.  
  561. iReceiveing = iLen - iReceiveded ;  
  562.  
  563. s.Receive(buf,iReceiveded,iReceiveing,SocketFlags.None) ;  
  564.  
  565. CommunClass.WriteTextToSocket(s,"OK") ;  
  566.  
  567. iReceiveded+= iReceiveing ;  
  568.  
  569. }  
  570.  
  571.  
  572.  
  573. strInfo = Encoding.UTF8.GetString(buf,0,iLen) ;  
  574.  
  575.  
  576.  
  577. return strInfo ;  
  578.  
  579. }  
  580.  
  581. /// <summary>  
  582.  
  583. /// 读取文件形式的可变信息  
  584.  
  585. /// </summary>  
  586.  
  587. /// <param name="s">要读取可变信息的Socket</param>  
  588.  
  589. /// <param name="strFile">读出后的文件保存位置</param>  
  590.  
  591. /// <returns>是否读取成功</returns>  
  592.  
  593. public static bool ReadDynamicFileFromSocket( Socket s,string strFile)  
  594.  
  595. {  
  596.  
  597. int iLen = ReadDynamicLenFromSocket(s) ;  
  598.  
  599. byte [] buf = new byte[iLen] ;  
  600.  
  601. FileStream fs = new FileStream(strFile,FileMode.Create,FileAccess.Write) ;  
  602.  
  603.  
  604.  
  605. try  
  606.  
  607. {  
  608.  
  609. int iReceiveded = 0 ;  
  610.  
  611. int iReceiveing = 0 ;  
  612.  
  613. while(iReceiveded<iLen)  
  614.  
  615. {  
  616.  
  617. if (iReceiveded + DEALLEN <= iLen)  
  618.  
  619. iReceiveing = DEALLEN ;  
  620.  
  621. else  
  622.  
  623. iReceiveing = iLen - iReceiveded ;  
  624.  
  625. s.Receive(buf,iReceiveded,iReceiveing,SocketFlags.None) ;  
  626.  
  627. CommunClass.WriteTextToSocket(s,"OK") ;  
  628.  
  629. iReceiveded+= iReceiveing ;  
  630.  
  631. }  
  632.  
  633. fs.Write(buf,0,iLen) ;  
  634.  
  635. return true ;  
  636.  
  637. }  
  638.  
  639. catch(Exception err)  
  640.  
  641. {  
  642.  
  643. MessageBox.Show("接收文件失败"+err.Message) ;  
  644.  
  645. return false ;  
  646.  
  647. }  
  648.  
  649. finally  
  650.  
  651. {  
  652.  
  653. fs.Close() ;  
  654.  
  655. }  
  656.  
  657. }  
  658.  
  659. }//end class  
  660.  
  661. }//end namespace  
  662.  
  663. 上面是俺的通讯基础类,有了这个类,再进行发送接受还不是小菜一碟吗?  
  664.  
  665. 上面介绍了通讯的基类,下面就是使用那个类进行发送和接收的部分:  
  666.  
  667. 二、发送部分:  
  668.  
  669. 发送咱们使用了多线程,可以同时进行多个任务,比如发送文件、发送文本等,互不影响:  
  670.  
  671. 发送文本方法:  
  672.  
  673. private void StartSendText(string strHost,int iPort,string strInfo)  
  674.  
  675. {  
  676.  
  677. SendText stText = new SendText(strHost,iPort,strInfo,new CommunClass.OnSend(OnSendDrawProgress)) ;  
  678.  
  679. StartThread(new ThreadStart(stText.Send)) ;  
  680.  
  681. }  
  682.  
  683. 下面是他调用用到的一些方法:  
  684.  
  685. 开始一个线程  
  686.  
  687. private void StartThread(ThreadStart target)  
  688.  
  689. {  
  690.  
  691. Thread doStep = new Thread(target) ;  
  692.  
  693. doStep.IsBackground = true ;  
  694.  
  695. doStep.Start() ;  
  696.  
  697. }  
  698.  
  699. 发送一部分(本文设置的是1024字节)成功后的回调方法  
  700.  
  701. public void OnSendDrawProgress(int iTotal,int iSending)  
  702.  
  703. {  
  704.  
  705. if (iTotal != pbMain.Maximum)  
  706.  
  707. pbMain.Maximum = iTotal ;  
  708.  
  709. pbMain.Value = iSending ;  
  710.  
  711. }  
  712.  
  713. 因为使用的是线程,所以发送文本使用的是一个发送文本类的方法,该类如下:  
  714.  
  715. public class SendText  
  716.  
  717. {  
  718.  
  719. private string Host ;  
  720.  
  721. private int Port ;  
  722.  
  723. private string Info ;  
  724.  
  725. private CommunClass.OnSend onsend ;  
  726.  
  727. public SendText(string strHost,int iPort,string strInfo,  
  728.  
  729. CommunClass.OnSend onSend)  
  730.  
  731. {  
  732.  
  733. Host = strHost ;  
  734.  
  735. Port = iPort ;  
  736.  
  737. Info = strInfo ;  
  738.  
  739. onsend = onSend ;  
  740.  
  741. }  
  742.  
  743. public void Send()  
  744.  
  745. {  
  746.  
  747. Socket s = null ;  
  748.  
  749. try  
  750.  
  751. {  
  752.  
  753. s = CommunClass.ConnectToServer(Host,Port) ;  
  754.  
  755.  
  756.  
  757. CommunClass.WriteCommandToSocket(s,"SENDTEXT") ;  
  758.  
  759. CommunClass.WriteCommandDescToSocket(s,"") ;  
  760.  
  761. CommunClass.WriteDynamicTextToSocket(s,Info,onsend) ;  
  762.  
  763. }  
  764.  
  765. catch (Exception e)  
  766.  
  767. {  
  768.  
  769. MessageBox.Show(e.Message) ;  
  770.  
  771. }  
  772.  
  773. finally  
  774.  
  775. {  
  776.  
  777. if (s != null)  
  778.  
  779. s.Close() ;  
  780.  
  781. }  
  782.  
  783. }  
  784.  
  785.  
  786.  
  787. }//end class  
  788.  
  789.  
  790.  
  791. 这样就可以使用一个线程发送文本了。  
  792.  
  793. 发送文件的方法也类似:  
  794.  
  795. private void StartSendFile(string strHost,int iPort,string strFile)  
  796.  
  797. {  
  798.  
  799. SendFile sfFile = new SendFile(strHost,iPort,strFile,this.pbMain) ;  
  800.  
  801. pbMain.Value = 0 ;  
  802.  
  803. StartThread(new ThreadStart(sfFile.Send)) ;  
  804.  
  805. }  
  806.  
  807. 发送文件的类:  
  808.  
  809. public class SendFile  
  810.  
  811. {  
  812.  
  813. private string Host ;  
  814.  
  815. private int Port ;  
  816.  
  817. private string FileToSend ;  
  818.  
  819. private ProgressBar pbar;  
  820.  
  821.  
  822.  
  823. public SendFile(string strHost,int iPort,string strFile,ProgressBar pbMain)  
  824.  
  825. {  
  826.  
  827. Host = strHost ;  
  828.  
  829. Port = iPort ;  
  830.  
  831. FileToSend = strFile ;  
  832.  
  833. pbar = pbMain ;  
  834.  
  835. }  
  836.  
  837. public void Send()  
  838.  
  839. {  
  840.  
  841. Socket s = null ;  
  842.  
  843. try  
  844.  
  845. {  
  846.  
  847. s = CommunClass.ConnectToServer(Host,Port) ;  
  848.  
  849.  
  850.  
  851. CommunClass.WriteCommandToSocket(s,"SENDFILE") ;  
  852.  
  853. CommunClass.WriteCommandDescToSocket(s,"") ;  
  854.  
  855.  
  856.  
  857. CommunClass.WriteFileToSocket(s,FileToSend,new CommunClass.OnSend(OnSendDrawProgress)) ;  
  858.  
  859. }  
  860.  
  861. catch (Exception e)  
  862.  
  863. {  
  864.  
  865. MessageBox.Show(e.Message) ;  
  866.  
  867. }  
  868.  
  869. finally  
  870.  
  871. {  
  872.  
  873. if (s != null)  
  874.  
  875. s.Close() ;  
  876.  
  877. }  
  878.  
  879. }  
  880.  
  881.  
  882.  
  883.  
  884.  
  885. public void OnSendDrawProgress(int iTotal,int iSending)  
  886.  
  887. {  
  888.  
  889. if (iTotal != pbar.Maximum)  
  890.  
  891. pbar.Maximum = iTotal ;  
  892.  
  893.  
  894.  
  895. pbar.Value = iSending ;  
  896.  
  897. }  
  898.  
  899.  
  900.  
  901. }//end class  
  902.  
  903. 当然,你发送一个命令让服务器端启动一个程序(靠,这不成木马了吗?)也可以:  
  904.  
  905. 俺这里只给出一部分代码,其余的您自己可以发挥以下:  
  906.  
  907. public class ExeCuteFile  
  908.  
  909. {  
  910.  
  911. private string Host ;  
  912.  
  913. private int Port ;  
  914.  
  915. private string FileName ;  
  916.  
  917. private string cmdParam ;  
  918.  
  919.  
  920.  
  921. public ExeCuteFile(string strHost,int iPort,string strFileName,string strCmdParam)  
  922.  
  923. {  
  924.  
  925. Host = strHost ;  
  926.  
  927. Port = iPort ;  
  928.  
  929. FileName = strFileName ;  
  930.  
  931. cmdParam = strCmdParam ;  
  932.  
  933. }  
  934.  
  935.  
  936.  
  937. public void Send()  
  938.  
  939. {  
  940.  
  941. Socket s = null ;  
  942.  
  943. try  
  944.  
  945. {  
  946.  
  947. s = CommunClass.ConnectToServer(Host,Port) ;  
  948.  
  949.  
  950.  
  951. CommunClass.WriteCommandToSocket(s,"EXECUTEFILE") ;  
  952.  
  953. CommunClass.WriteCommandDescToSocket(s,FileName) ;  
  954.  
  955. CommunClass.WriteDynamicTextToSocket(s,"",null) ;  
  956.  
  957. MessageBox.Show(CommunClass.ReadDynamicTextFromSocket(s)) ;  
  958.  
  959. }  
  960.  
  961. catch (Exception e)  
  962.  
  963. {  
  964.  
  965. MessageBox.Show(e.Message) ;  
  966.  
  967. }  
  968.  
  969. finally  
  970.  
  971. {  
  972.  
  973. if (s != null)  
  974.  
  975. s.Close() ;  
  976.  
  977. }  
  978.  
  979.  
  980.  
  981. }  
  982.  
  983. }  
  984.  
  985. 三、下面是服务器端接受信息的代码:  
  986.  
  987. 创建监听:  
  988.  
  989. /// <summary>  
  990.  
  991. /// 再给定的主机和端口上创建监听程序  
  992.  
  993. /// </summary>  
  994.  
  995. /// <param name="strAddress"></param>  
  996.  
  997. /// <param name="iPort"></param>  
  998.  
  999. private void BuildingServer(string strAddress,int iPort)  
  1000.  
  1001. {  
  1002.  
  1003. IPAddress ipAddress = Dns.Resolve(strAddress).AddressList[0];  
  1004.  
  1005.  
  1006.  
  1007. try  
  1008.  
  1009. {  
  1010.  
  1011. listener = new TcpListener(ipAddress, iPort);  
  1012.  
  1013. }  
  1014.  
  1015. catch ( Exception e)  
  1016.  
  1017. {  
  1018.  
  1019. AddInfo(e.Message) ;  
  1020.  
  1021. }  
  1022.  
  1023. }  
  1024.  
  1025.  
  1026. 开始监听:  
  1027.  
  1028.  
  1029. /// <summary>  
  1030.  
  1031. /// 开始监听  
  1032.  
  1033. /// </summary>  
  1034.  
  1035. private void StartListen()  
  1036.  
  1037. {  
  1038.  
  1039. bool done = false;  
  1040.  
  1041.  
  1042.  
  1043. listener.Start();  
  1044.  
  1045. while (!done)  
  1046.  
  1047. {  
  1048.  
  1049. Socket s = listener.AcceptSocket() ;  
  1050.  
  1051. if(s != null)  
  1052.  
  1053. {  
  1054.  
  1055. DealWithSocket dws = new DealWithSocket(s,this.tbLog) ;  
  1056.  
  1057. StartThread(new ThreadStart(dws.DealWith)) ;  
  1058.  
  1059. }  
  1060.  
  1061. }  
  1062.  
  1063. }  
  1064.  
  1065.  
  1066.  
  1067. private void StartThread(ThreadStart target)  
  1068.  
  1069. {  
  1070.  
  1071. Thread doStep = new Thread(target) ;  
  1072.  
  1073. doStep.IsBackground = true ;  
  1074.  
  1075. doStep.Start() ;  
  1076.  
  1077. }  
  1078.  
  1079.  
  1080.  
  1081. 开始监听后,对于每一个监听到的客户端的连接都用一个单独的线程来处理,处理通过类DealWithSocket来完成,下面是类代码:  
  1082.  
  1083. public class DealWithSocket  
  1084.  
  1085. {  
  1086.  
  1087. private Socket s = null ;  
  1088.  
  1089. private TextBox tbLog = null ;  
  1090.  
  1091. public DealWithSocket(Socket newSocket,TextBox tbInfo)  
  1092.  
  1093. {  
  1094.  
  1095. s = newSocket ;  
  1096.  
  1097. tbLog = tbInfo ;  
  1098.  
  1099. }  
  1100.  
  1101.  
  1102.  
  1103. public void DealWith()  
  1104.  
  1105. {  
  1106.  
  1107. string strCmd = CommunClass.ReadCommandFromSocket(s) ;  
  1108.  
  1109. string strDesc = CommunClass.ReadCommandDescFromSocket(s) ;  
  1110.  
  1111. AddInfo(strCmd) ;  
  1112.  
  1113. switch(strCmd)  
  1114.  
  1115. {  
  1116.  
  1117. case "SENDFILE" :  
  1118.  
  1119. CommunClass.ReadDynamicFileFromSocket(s,"e://rrr.txt") ;  
  1120.  
  1121. break ;  
  1122.  
  1123. case "EXECUTEFILE" :  
  1124.  
  1125. string strParam = CommunClass.ReadDynamicTextFromSocket(s) ;  
  1126.  
  1127. string strResult = ExeCuteFile(strDesc,strParam) ;  
  1128.  
  1129. CommunClass.WriteDynamicTextToSocket(s,strResult,null) ;  
  1130.  
  1131. break ;  
  1132.  
  1133. default:  
  1134.  
  1135. string strDetail = CommunClass.ReadDynamicTextFromSocket(s) ;  
  1136.  
  1137. AddInfo(strDetail) ;  
  1138.  
  1139. break ;  
  1140.  
  1141. }  
  1142.  
  1143. try  
  1144.  
  1145. {  
  1146.  
  1147. s.Close() ;  
  1148.  
  1149. }  
  1150.  
  1151. catch (Exception e)  
  1152.  
  1153. {  
  1154.  
  1155. AddInfo(e.Message) ;  
  1156.  
  1157. }  
  1158.  
  1159. }  
  1160.  
  1161. private void AddInfo(string strInfo)  
  1162.  
  1163. {  
  1164.  
  1165. string Info = DateTime.Now.ToLongTimeString() + " "+ strInfo +"/r/n" ;  
  1166.  
  1167. tbLog.Text += Info ;  
  1168.  
  1169. tbLog.Refresh() ;  
  1170.  
  1171. }  
  1172.  
  1173. private string ExeCuteFile(string strFileName,string strCmdParam)  
  1174.  
  1175. {  
  1176.  
  1177. System.Diagnostics.Process proc = new System.Diagnostics.Process() ;  
  1178.  
  1179. proc.StartInfo.FileName = strFileName ;  
  1180.  
  1181. proc.StartInfo.Arguments = strCmdParam ;  
  1182.  
  1183. try  
  1184.  
  1185. {  
  1186.  
  1187. proc.Start() ;  
  1188.  
  1189. return "OK" ;  
  1190.  
  1191. }  
  1192.  
  1193. catch(Exception err)  
  1194.  
  1195. {  
  1196.  
  1197. return err.Message ;  
  1198.  
  1199. }  
  1200.  
  1201. }  
  1202.  
  1203. }//end class  
  1204.  
  1205.  
  1206.  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值