c#的socket通信应用.文件较多.附件为工程. 
core
  AbstractBytesWorker.cs    字节工作器(基类),用于用于同一不同功能的字节工作器 
BinaryHand.cs  2进制处理器.  ThDispose.cs 处理回收相关
  crc  
entity
  ThPersonInfo.cs
  manager
  ThSocketManager.cs  ThSocketManagerBusiness.cs
所有的业务
  request 
RequestCode.cs  请求码 
ThProtocolReq.cs 请求逻辑 
ThReqBytesWorker.cs 请求相关的字节工作器
  response
  respLogic
    ThProtocolResp.cs 处理服务器响应的数据.
    ThProtocolRespDelegates.cs 所有的代理.用于通知客户的事件.
    ThProtocolRespEvents.cs 所有的事件.用于调用客户的. 
  ThProtocolRespListeners.cs 所有的监听器,用于控制事件如何订阅
    ThProtocolRespLogic.cs 处理服务器的数据 
  ThRespBytesWorker.cs 响应字节处理器
  BinaryMessageHandler.cs 处理数据包粘结,包一次数据不足等情况. 
ResponseCode.cs 响应码
  socket
  TAsyncTcpClient.cs tcpClient类,read异步.
  testcase 
===============================================================
  部分类代码:  BinaryMessageHandler

  1. #pragma warning disable 0219
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.IO;
  7. /// <summary>
  8. /// 字节接收处理,粘包问题
  9. /// </summary>
  10. class BinaryMessageHandler : ThDispose
  11. {
  12. List<byte> bytesList = new List<byte>();
  13. private TAsyncTcpClient tcpClient;
  14. public BinaryMessageHandler(TAsyncTcpClient tcpClient)
  15. {
  16. this.tcpClient = tcpClient;
  17. }
  18. public BinaryMessageHandler()
  19. {
  20. }
  21. override public void SelfDispose()
  22. {
  23. tcpClient = null;
  24. bytesList = null;
  25. }
  26. /// <summary>
  27. /// 累积 字节.
  28. /// 每次累积后,测试是否有完整的包.
  29. /// </summary>
  30. /// <param name="buf"></param>
  31. public void Write(byte[] buf)
  32. {
  33. if (buf.Length > 0)
  34. {
  35. //累积字节
  36. bytesList.AddRange(buf);
  37. byte[] bytes = bytesList.ToArray<byte>();
  38. MemoryStream ms = new MemoryStream(bytes);
  39. BinaryReader reader = new BinaryReader(ms);
  40. int header = reader.ReadUInt16();
  41. if (header == ThSocketManager.TH_HEADER)
  42. {
  43. int len = reader.ReadUInt16();
  44. int remainLen = len - 4;
  45. if ((ms.Length - ms.Position) >= remainLen)
  46. {
  47. //有完整的数据包
  48. ms.Position = 0;
  49. byte[] pack = reader.ReadBytes(len);
  50. ReadPackage(pack);
  51. //移除读完的数据包
  52. bytesList.RemoveRange(0, len);
  53. }
  54. }
  55. reader.Close();
  56. ms.Close();
  57. }
  58. }
  59. /// <summary>
  60. /// 读取服务端响应信息.
  61. /// </summary>
  62. /// <param name="bytes"></param>
  63. /// <returns></returns>
  64. public void ReadPackage(byte[] bytes)
  65. {
  66. //处理包头
  67. MemoryStream ms = new MemoryStream(bytes);
  68. ms.Position = 0;
  69. BinaryReader reader = new BinaryReader(ms, Encoding.UTF8);
  70. ushort header = reader.ReadUInt16();
  71. ushort totalLen = reader.ReadUInt16();
  72. ushort respCode = reader.ReadUInt16();
  73. short signature = reader.ReadInt16();
  74. int dataLen = totalLen - ThSocketManager.PREFIX_LENGTH;
  75. byte[] dataBytes = reader.ReadBytes(dataLen);
  76. reader.Close();
  77. ms.Close();
  78. //调用服务端响应,包体处理器.
  79. tcpClient.thProtocolResp.ResponseHandler(respCode, dataBytes);
  80. }
  81. }

BinaryHand

  1. #pragma warning disable 0219
  2. using System.Text;
  3. using System.IO;
  4. class BinaryHand
  5. {
  6. /// <summary>
  7. /// 准备将数据发送至服务端
  8. /// </summary>
  9. /// <param name="clientId"></param>
  10. /// <param name="data"></param>
  11. /// <returns></returns>
  12. public static byte[] ToBytes(ushort requestCode, uint clientId, byte[] dataBytes)
  13. {
  14. MemoryStream ms = new MemoryStream();
  15. BinaryWriter writer = new BinaryWriter(ms);
  16. //2 ushort header
  17. writer.Write(ThSocketManager.TH_HEADER);
  18. //2 ushort total length
  19. ushort packageLen = ThSocketManager.PREFIX_LENGTH;
  20. if (dataBytes != null)
  21. {
  22. packageLen += (ushort)dataBytes.Length;
  23. }
  24. writer.Write(packageLen);
  25. //2 ushort protocol id
  26. writer.Write(requestCode);
  27. //2 short signature
  28. writer.Write((short)0);
  29. //4 unit client id
  30. //writer.Write(clientId);
  31. //x string data
  32. if (dataBytes != null)
  33. writer.Write(dataBytes);
  34. //计算crc,并写入[6,7]位置.
  35. byte[] tmpBytes = ms.ToArray();
  36. short signature = CRC16.Compute(tmpBytes);
  37. long oldPos = ms.Position;
  38. ms.Position = 6;
  39. writer.Write(signature);
  40. ms.Position = oldPos;
  41. //准备输出
  42. byte[] bytes = ms.ToArray();
  43. writer.Close();
  44. ms.Close();
  45. return bytes;
  46. }
  47. public static byte[] ToBytes(RequestCode requestCode, uint clientId, byte[] dataBytes)
  48. {
  49. return ToBytes((ushort)requestCode, clientId, dataBytes);
  50. }
  51. public byte[] ToBytes(uint clientId, string data)
  52. {
  53. byte[] dataBytes = Encoding.UTF8.GetBytes(data);
  54. return ToBytes(RequestCode.None, clientId, dataBytes);
  55. }
  56. /// <summary>
  57. /// 读取服务端响应信息.
  58. /// </summary>
  59. /// <param name="bytes"></param>
  60. /// <returns></returns>
  61. public byte[] FromBytes(byte[] bytes)
  62. {
  63. MemoryStream ms = new MemoryStream(bytes);
  64. ms.Position = 0;
  65. BinaryReader reader = new BinaryReader(ms, Encoding.UTF8);
  66. ushort header = reader.ReadUInt16();
  67. ushort totalLen = reader.ReadUInt16();
  68. ushort protocolId = reader.ReadUInt16();
  69. short signature = reader.ReadInt16();
  70. uint clientId = reader.ReadUInt32();
  71. int dataLen = totalLen - ThSocketManager.PREFIX_LENGTH;
  72. byte[] dataBytes = reader.ReadBytes(dataLen);
  73. reader.Close();
  74. ms.Close();
  75. return dataBytes;
  76. }
  77. }

c# socket通信较完善方案的更多相关文章

  1. C#应用视频教程1.3 Socket通信客户端完善

    我们先把前面的代码封装成一个完整的类,因为跟网络相关的方法并不一定是建立socket的服务器和客户端,所以还是应该把两个分开,比如获取本机IP,修改本机IP,PING远程主机这些事情应该放在一个单独的 ...

  2. Socket 通信(基础原理、实时聊天系统雏形)

    什么是 Socket? Socket 英文直译为"孔或插座",也称为套接字.用于描述 IP 地址和端口号,是一种进程间的通信机制.你可以理解为 IP 地址确定了网内的唯一计算机,而 ...

  3. Java多线程技术:实现多用户服务端Socket通信

    目录 前言回顾 一.多用户服务器 二.使用线程池实现服务端多线程 1.单线程版本 2.多线程版本 三.多用户与服务端通信演示 四.多用户服务器完整代码 最后 前言回顾 在上一篇<Java多线程实 ...

  4. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-介绍

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  5. socket通信

    socket通信 一:socket基于Tcp连接,数据传输有保证 二:socket连接的建立过程: 1:服务器监听 2:客户端发出请求 3:建立连接 4:通信 三:一个简单的例子:服务器端每隔一段时间 ...

  6. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

  7. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-完整应用例子-在线聊天室系统-下载配置

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

  8. C# socket通信

    最近在研究socket,今天看到很好的一篇关于socket通信的文章,故收藏了,慢慢琢磨. 我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念: 1.TCP/IP层次模型 当然这里 ...

  9. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

随机推荐

  1. Oracle中将小数转换成字符丢零.截取小数.除数为零解决法

    如下所示,前面少个0 SQL>select money from users where username ='LEI'; money --------- .3256 解决方法: SQL> ...

  2. chrome console js多行输入

    一直以来,Chrome控制台都缺少象IE调试台那样的多行执行模式.  今天意外发现Chrome其实也支持多行模式.默认在Chrome控制台上输入回车后会执行该命令,只需要通过输入Shift+Enter ...

  3. elementaryOS系统托盘解决方案

    在用 eOS 的时候,你可能会遇到系统托盘的问题,有些需要托盘的软件比如说 QQ,没办法在 eOS 的 Wingpanel 上显示,一最小化就不见了,或者出现一个 System tray 的窗口,很麻 ...

  4. (原创)LAMP教程4-用VirtualBox安装64位的centos6.4

    (原创)LAMP教程4-用VirtualBox安装64位的centos6.4 好的,今天就要开始正式的讲一些有营养的东西了,是的,没有错就是讲如何用VirtualBox安装64位的centos6.4 ...

  5. 试验笔记 - Eclipse的.class反编译插件

    常用的反编译工具有: JAD Java Decompiler Download Mirror(?) http://varaneckas.com/jad/ JadClipse (较好) http://j ...

  6. PHP:产生不重复随机数的方法

    来源:http://www.ido321.com/1217.html 无论是Web应用,还是WAP或者移动应用,随机数都有其用武之地.在最近接触的几个小项目中,我也经常需要和随机数或者随机数组打交道, ...

  7. Fast Intro To Java Programming (2)

    Java局部变量 局部变量声明在方法.构造方法或者语句块中: 局部变量在方法.构造方法.或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁: 访问修饰符不能用于局部变量: 局部变量只在声明它 ...

  8. xmpp 协议之可扩展消息(messaging)与状态(presence)协议核心: RFC 3920

    附:asmack已经不需要了,4.1以后的smack已经可以在android上使用了. XMPP Clients:   http://xmpp.org/software/clients.html An ...

  9. 我从其他人的Shell脚本中学到的

    我从其他人的Shell脚本中学到的 2013/08/20 | 分类: 程序员 | 2 条评论 | 标签: SHELL, 脚本 分享到:17 本文由 伯乐在线 - 伯乐在线读者 翻译自 Fizer Kh ...

  10. DBMS_ERRLOG记录DML错误日志(一)

    当一个DML运行的时候,如果遇到了错误,则这条语句会整个回滚,就好像没有执行过.不过对于一个大的DML而言,如果个别数据错误而导致整个语句的回滚,会浪费很多的资源和运行时间,从10g开始Oracle支 ...