分类
C#进行点对点通讯和文件传输(通讯基类部分)‖
| using System; |
| using System.Net.Sockets; |
| using System.Net ; |
| using System.IO ; |
| using System.Windows.Forms; |
| using System.Text; |
| namespace BaseClass |
| { |
| /// <summary> |
| /// 传送信息的 的长度信息+可变长度的信 | 格式为 给定长度的命令部分+给 息部分 | 定长度的命令注释部分+可变长度 |
| /// </summary> |
| public class CommunClass |
| { |
| public CommunClass() |
| { |
| // |
| // TODO: 在此处添加构造函数逻辑 |
| // |
| } |
| /// <summary> |
| /// 命令部分的长度 |
| /// </summary> |
| private st | atic readonly int CMDLEN = 5 | 0 ; |
| /// <summary> |
| /// 命令注释部分的长度 |
| /// </summary> |
| rivate st | atic readonly int DESCLEN = | 100 ; |
| /// <summary> |
| /// 可变长度的长度信息部分所占的字节数 |
| /// </summary> |
| private static readonl | y int DYNAMICLENGTHLEN = 10 ; |
| /// <summary> |
| /// 每次处理可变信息部分的长度 |
| /// </summary> |
| private static readonl | y int DEALLEN = 1024 ; |
| /// <summary> |
| /// /应答的最大长度 |
| /// </summary> |
| private st | atic readonly int RESPONLEN | = 20 ; |
| /// <summary> |
| /// 用于填充命令或注筒蛔愠ざ炔糠值淖址?nbsp; |
| /// </summary> |
| private static readonl | y char FILLCHAR = '^' ; |
| /// <summary> |
| /// 成功发 说还不是) | 送一部分数据后的回调方法(也 | 可以认为是触发的事件,但严格来 |
| /// </summary> |
| public del | egate void OnSend(int iTotal | ,int iSending) ; |
| /// <summary> |
| /// 根据给定的服务器和端口号建立连接 |
| /// </summary> |
| /// <param name="strHost">服务器名</param> |
| /// <param name="iPort">端口号</param> |
| /// <returns></returns> |
| public stat | ic Socket ConnectToServer(st | ring strHost,int iPort) |
| { |
| try |
| { |
| IPAddress ipA | ddress = Dns.Resolve(strHost).AddressList[0]; |
| IPEndPoint ip | Point = new IPEndPoint(ipAddress,iPort) ; |
| S ork,SocketType.Stream,Pr | ocket s = new Socket(Address otocolType.Tcp) ; | Family.InterNetw |
| s.Connect(ipPoint) ; |
| return s ; |
| } |
| catch (Exception e) |
| { |
| t e.Message)) ; | hrow (new Exception("建立到 | 服务器的连接出错" + |
| } |
| } |
| /// <summary> |
| /// 将文本写到Socket中 |
| /// </summary> |
| /// <param name="s">要发送信息的Socket</param> |
| /// <param name="strInfo">要发送的信息</param> |
| /// <returns>是否成功</returns> |
| public static bool Writ | eTextToSocket(Socket s,string strInfo) |
| { |
| byte [ | ] buf = Encoding.UTF8.GetByt | es(strInfo) ; |
| try |
| { |
| s | .Send(buf,0,buf.Length,Socke | tFlags.None) ; |
| return true ; |
| } |
| catch(Exception err) |
| { |
| MessageBox.Sh | ow("发送文本失败!"+err.Message) ; |
| return false ; |
| } |
| } |
| /// <summary> |
| /// 将命令文本写到Socket中 |
| /// </summary> |
| /// <param name="s">要发送命令文本的Socket</param> |
| /// <param name="strInfo">要发送的命令文本</param> |
| /// <returns>是否成功</returns> |
| public stat | ic bool WriteCommandToSocket | (Socket s,string strCmd) |
| { |
| if (strCmd == "") |
| strCmd = "NOP" ; |
| strCmd = strCmd.Pa | dRight(CMDLEN,FILLCHAR) ; |
| return | WriteTextToSocket(s,strCmd) | ; |
| } |
| /// <summary> |
| /// 将命令注释写到Socket中 |
| /// </summary> |
| /// <param name="s">要发送命令注释的Socket</param> |
| /// <param name="strInfo">要发送的命令注释</param> |
| /// <returns>是否成功</returns> |
| public stat | ic bool WriteCommandDescToSo | cket(Socket s,string strDesc) |
| { |
| if (strDesc == "") |
| strDesc = "0" ; |
| strDesc = strDesc. | PadRight(DESCLEN,FILLCHAR) ; |
| return | WriteTextToSocket(s,strDesc | ) ; |
| } |
| /// <summary> |
| /// 发送可变信息的字节数 |
| /// </summary> |
| /// <param name="s">要发送字节数的Socket</param> |
| /// <param name="iLen">字节数</param> |
| /// <returns>是否成功</returns> |
| public static bool Writ | eDynamicLenToSocket(Socket s,int iLen) |
| { |
| string strLen = iL YNAMICLENGTHLEN,FILLCHAR) ; | en.ToString().PadRight(D |
| return | WriteTextToSocket(s,strLen) | ; |
| } |
| /// <summary> |
| /// 将缓存的指定部分发送到Socket |
| /// </summary> |
| /// <param name="s">要发送缓存的Socket</param> |
| /// <param name="buf">要发送的缓存</param> |
| /// <param name="iStart">要发送缓存的起始位置</param> |
| /// <param name="iCount">要发送缓存的字节数</param> |
| /// <param name="iBlock">每次发送的字节说</param> |
| /// <param name="SendSuccess">每次发送成功后的回调函数</param> |
| /// <returns>是否发送成功</returns> |
| public stat iStart,int iCount,int iB | ic bool WriteBufToSocket(Soc lock,OnSend SendSuccess) | ket s,byte [] buf,int |
| { |
| int iSended = 0 ; |
| int iSending = 0 ; |
| while(iSended<iCount) |
| { |
| if (iSended + | iBlock <= iCount) |
| iSending = iBlock ; |
| else |
| iSending | = iCount - iSended ; |
| s | .Send(buf,iStart+iSended,iSe | nding,SocketFlags.None) ; |
| iSended += iSending ; |
| i | f (ReadResponsionFromSocket( | s)=="OK") |
| if (SendSuccess != null) |
| | SendSuccess(iCount,iSend | ed) ; |
| else |
| return false; |
| } |
| return true ; |
| } |
| /// <summary> |
| /// 将长度不固定文本发送到socket |
| /// </summary> |
| /// <param name="s">要发送文本的Socket</param> |
| /// <param name="strText">要发送的文本</param> |
| /// <param name="OnSendText">成功发送一部分文本后的回调函数</param> |
| /// <param name="settextlen">得到文本长度的回调函数</param> |
| /// <returns></returns> |
| public stat | ic bool WriteDynamicTextToSo | cket(Socket s,string strText, |
| OnSend OnSendText) |
| { |
| byte [ | ] buf = Encoding.UTF8.GetByt | es(strText) ; |
| int iLen = buf.Length ; |
| try |
| { |
| WriteDynamicL | enToSocket(s,iLen) ; |
| r | eturn WriteBufToSocket(s,buf | ,0,iLen,DEALLEN,OnSendText) ; |
| } |
| catch(Exception err) |
| { |
| M | essageBox.Show("发送文本失败 | !"+err.Message) ; |
| return false ; |
| } |
| } |
| /// <summary> |
| /// 将文件写到Socket |
| /// </summary> |
| /// <param name="s">要发送文件的Socket</param> |
| /// <param name="strFile">要发送的文件</param> |
| /// <returns>是否成功</returns> |
| public static bool Writ | eFileToSocket(Socket s,string strFile, |
| OnSend OnSendFile) |
| { |
| FileSt en,FileAccess.Read,FileS | ream fs = new FileStream(str hare.Read) ; | File,FileMode.Op |
| int iLen = (int)fs.Length ; |
| WriteDynamicLenToS | ocket(s,iLen) ; |
| byte [] buf = new byte[iLen] ; |
| try |
| { |
| fs.Read(buf,0,iLen) ; |
| r | eturn WriteBufToSocket(s,buf | ,0,iLen,DEALLEN,OnSendFile) ; |
| } |
| catch(Exception err) |
| { |
| M | essageBox.Show("发送文件失败 | !"+err.Message) ; |
| return false ; |
| } |
| finally |
| { |
| fs.Close() ; |
| } |
| } |
| /// <summary> |
| /// 对方对自己消息的简单回应 |
| /// </summary> |
| /// <param name="s"></param> |
| /// <returns></returns> |
| public static string Re | adResponsionFromSocket( Socket s) |
| { |
| byte [ | ] bufCmd = new byte[RESPONLE | N] ; |
| int iCount = s.Receive(bufCmd) ; |
| string strRespon = | Encoding.UTF8.GetString(bufCmd,0,iCount) ; |
| return strRespon ; |
| } |
| /// <summary> |
| /// 从Socket读取命令 |
| /// </summary> |
| /// <param name="s">要读取命令的Socket</param> |
| /// <returns>读取的命令</returns> |
| public static string Re | adCommandFromSocket( Socket s) |
| { |
| byte [ | ] bufCmd = new byte[CMDLEN] | ; |
| int iCount = s.Rec | eive(bufCmd,0,CMDLEN,SocketFlags.Partial) ; |
| string strCommand | = Encoding.UTF8.GetString(bufCmd,0,CMDLEN) ; |
| return strCommand | = strCommand.TrimEnd(FILLCHAR) ; |
| } |
| /// <summary> |
| /// 读取命令注释 |
| /// </summary> |
| /// <param name="s">要读取命令注释的Socket</param> |
| /// <returns>读取的命令注释</returns> |
| public static string Re | adCommandDescFromSocket( Socket s) |
| { |
| byte [] bufCmd = n | ew byte[DESCLEN] ; |
| int iC | ount = s.Receive(bufCmd,0,DE | SCLEN,SocketFlags.Partial) ; |
| string | strCommand = Encoding.UTF8. | GetString(bufCmd,0,DESCLEN) ; |
| return strCommand | = strCommand.TrimEnd(FILLCHAR) ; |
| } |
| /// <summary> |
| /// 读取可变部分的长度 |
| /// </summary> |
| /// <param name="s">要读取可变部分长度的Socket</param> |
| /// <returns>读取的可变部分的长度</returns> |
| public static int ReadD | ynamicLenFromSocket( Socket s) |
| { |
| byte [] bufCmd = n | ew byte[DYNAMICLENGTHLEN] ; |
| int iCount = s.Rec GTHLEN,SocketFlags.Partial) ; | eive(bufCmd,0,DYNAMICLEN |
| string ,0,DYNAMICLENGTHLEN) ; | strCommand = Encoding.UTF8. | GetString(bufCmd |
| return int.Parse(s | trCommand.TrimEnd(FILLCHAR)) ; |
| } |
| /// <summary> |
| /// 读取文本形式的可变信息 |
| /// </summary> |
| /// <param name="s">要读取可变信息的Socket</param> |
| /// <returns>读取的可变信息</returns> |
| public static string Re | adDynamicTextFromSocket( Socket s) |
| { |
| int iL | en = ReadDynamicLenFromSock | et(s) ; |
| byte [] buf = new byte[iLen] ; |
| string strInfo = "" ; |
| int iReceiveded = 0 ; |
| int iReceiveing = 0 ; |
| while(iReceiveded<iLen) |
| { |
| if (iReceived | ed + DEALLEN <= iLen) |
| iReceiveing = DEALLEN ; |
| else |
| | iReceiveing = iLen - iRe | ceiveded ; |
| s.Receive(buf | ,iReceiveded,iReceiveing,SocketFlags.None) ; |
| CommunClass.W | riteTextToSocket(s,"OK") ; |
| iReceiveded+= iReceiveing ; |
| } |
| strInf | o = Encoding.UTF8.GetString( | buf,0,iLen) ; |
| return strInfo ; |
| } |
| /// <summary> |
| /// 读取文件形式的可变信息 |
| /// </summary> |
| /// <param name="s">要读取可变信息的Socket</param> |
| /// <param name="strFile">读出后的文件保存位置</param> |
| /// <returns>是否读取成功</returns> |
| public static bool Read ) | DynamicFileFromSocket( Socket s,string strFile |
| { |
| int iLen = ReadDy | namicLenFromSocket(s) ; |
| byte [] buf = new byte[iLen] ; |
| FileSt eate,FileAccess.Write) ; | ream fs = new FileStream(str | File,FileMode.Cr |
| try |
| { |
| int iReceiveded = 0 ; |
| int iReceiveing = 0 ; |
| while(iReceiveded<iLen) |
| { |
| if (iRece | iveded + DEALLEN <= iLen) |
| iReceiveing = DEALLEN ; |
| else |
| | iReceiveing = iLen - | iReceiveded ; |
| s.Receiv veing,SocketFlags.None) ; | e(buf,iReceiveded,iRecei |
| CommunCl | ass.WriteTextToSocket(s,"OK") ; |
| iReceiveded+= iReceiveing ; |
| } |
| fs.Write(buf,0,iLen) ; |
| return true ; |
| } |
| catch(Exception err) |
| { |
| M | essageBox.Show("接收文件失败 | "+err.Message) ; |
| return false ; |
| } |
| finally |
| { |
| fs.Close() ; |
| } |
| } |
| }//end class |
| }//end namespace |