using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading; namespace EventBase
{
/*解决Socket的粘包处理
使用方法
A2DTcpClient client = new A2DTcpClient("127.0.0.1", 5000);
client.NewMessageReceived += new MessageReceived(client_NewMessageReceived);
client.Connect();
client.Send("HELLO");
client.Close();
static void client_NewMessageReceived(string msg)
{
Console.WriteLine(msg);
}
*/
public delegate void MessageReceived(string msg);
public class A2DTcpClient
{
public const string terminateString = "\r\n"; //消息的结尾标记
public const int receiveBufferSize = 1024; //缓冲区大小 private string RemoteServer { get; set; }
private int RemotePort { get; set; }
private TcpClient tcpClient; public event MessageReceived NewMessageReceived; public A2DTcpClient(string remoteServer, int remotePort)
{
this.RemotePort = remotePort;
this.RemoteServer = remoteServer;
tcpClient = new TcpClient();
} public void Connect()
{
if (tcpClient.Connected)
throw new Exception("Connected, cannot re-connect.");
tcpClient.Connect(this.RemoteServer, this.RemotePort);
ThreadPool.QueueUserWorkItem(new WaitCallback(ReceiveMessage), tcpClient.Client);
Thread.Sleep(2000);//强制暂停,为了上面的线程运行
} public void Close()
{
if (!tcpClient.Connected)
throw new Exception("Closed, cannot re-close.");
tcpClient.Close();
} StringBuilder sb = new StringBuilder(); //这个是用来保存:接收到了的,但是还没有结束的消息
public void ReceiveMessage(object state) //这个函数会被以线程方式运行
{
Socket socket = (Socket)state;
while (true)
{
byte[] buffer = new byte[receiveBufferSize]; //buffer大小,此处为1024
int receivedSize = socket.Receive(buffer); string rawMsg = System.Text.Encoding.Default.GetString(buffer, 0, receivedSize);
int rnFixLength = terminateString.Length; //这个是指消息结束符的长度,此处为\r\n
for (int i = 0; i < rawMsg.Length; ) //遍历接收到的整个buffer文本
{
if (i <= rawMsg.Length - rnFixLength)
{
if (rawMsg.Substring(i, rnFixLength) != terminateString) //非消息结束符,则加入sb
{
sb.Append(rawMsg[i]);
i++;
}
else
{
this.OnNewMessageReceived(sb.ToString()); //找到了消息结束符,触发消息接收完成事件
sb.Clear();
i += rnFixLength;
}
}
else
{
sb.Append(rawMsg[i]);
i++;
}
}
}
}
private void OnNewMessageReceived(string msg)
{
if (this.NewMessageReceived != null)
this.NewMessageReceived.Invoke(msg);
} public void Send(string str)
{
if (!this.tcpClient.Connected)
throw new Exception("Closed, cannot send data.");
str += terminateString;
byte[] byteArray = System.Text.Encoding.Default.GetBytes(str);
this.tcpClient.Client.Send(byteArray);
}
}
}

c# Socket通讯中关于粘包,半包的处理,加分割符的更多相关文章

  1. Netty 粘包/半包原理与拆包实战

    Java NIO 粘包 拆包 (实战) - 史上最全解读 - 疯狂创客圈 - 博客园 https://www.cnblogs.com/crazymakercircle/p/9941658.html 本 ...

  2. 关于Socket通讯中的Close_wait状态

    关于Socket通讯中的Close_wait状态 文/转 编辑 编者按:使用Socket通讯,有时我们查看端口状态的时候,经常会发现Socket处于close_wait状态,从而影响系统性能,此文或许 ...

  3. Http 调用netty 服务,服务调用客户端,伪同步响应.ProtoBuf 解决粘包,半包问题.

    实际情况是: 公司需要开发一个接口给新产品使用,需求如下 1.有一款硬件设备,客户用usb接上电脑就可以,但是此设备功能比较单一,所以开发一个服务器程序,辅助此设备业务功能 2.解决方案,使用Sock ...

  4. netty解决粘包半包问题

    前言:开发者用到TCP/IP交互时,偶尔会遇到粘包或者半包的数据,这种情况有时会对我们的程序造成严重的影响,netty框架为解决这种问题提供了若干框架 1. LineBasedFrameDecoder ...

  5. [转]SOCKET通信中TCP、UDP数据包大小的确定

    TCP.UDP数据包大小的确定 UDP和TCP协议利用端口号实现多项应用同时发送和接收数据.数据通过源端口发送出去,通过目标端口接收.有的网络应用只能使用预留或注册的静态端口:而另外一些网络应用则可以 ...

  6. 11.1、socket连接中的粘包、精确传输问题

    粘包: 发生原因: 当调用send的时候,数据并不是即时发给客户端的.而是放到了系统的socket发送缓冲区里,等缓冲区满了.或者数据等待超时了,数据才会发送,所以有时候发送太快的话,前一份数据还没有 ...

  7. Python中,我该如何切分字符串后保留分割符?

    原文来源:https://stackoverflow.com/questions/2136556/in-python-how-do-i-split-a-string-and-keep-the-sepa ...

  8. socket编程 TCP 粘包和半包 的问题及解决办法

    一般在socket处理大数据量传输的时候会产生粘包和半包问题,有的时候tcp为了提高效率会缓冲N个包后再一起发出去,这个与缓存和网络有关系. 粘包 为x.5个包 半包 为0.5个包 由于网络原因 一次 ...

  9. Netty - 粘包和半包(上)

    在网络传输中,粘包和半包应该是最常出现的问题,作为 Java 中最常使用的 NIO 网络框架 Netty,它又是如何解决的呢?今天就让我们来看看. 定义 TCP 传输中,客户端发送数据,实际是把数据写 ...

随机推荐

  1. [Unity 设计模式]桥接模式(BridgePattern)

    1.前言 继上一讲IOC模式的基础上继续本讲桥接模式,笔者感觉桥接模式是23种设计模式中桥接模式是最好用但也是最难理解的设计模式之一,23中设计模式就好武侠剧中一本武功秘籍,我们在工作过程中想要熟练运 ...

  2. JS学习一

    js中的变量输出   [使用JS的三种方式] 1. 在HTML标签中,直接内嵌JS(并不提倡使用): <button onclick="alert('你真点啊!')"> ...

  3. 集美大学网络1413第七次作业成绩(团队三) --需求改进&系统设计

    题目 团队作业3--需求改进&系统设计 团队作业3成绩  团队/分值 TD BZ GJ CJ SI WBS GS JG DB SS SJ CS DC 总分  1 0.25 0.75 1 0.5 ...

  4. 【Alpha】——Sixth Scrum Meeting

    一.今日站立式会议照片 二.每个人的工作 成员 昨天已完成的工作 今天计划完成的工作 李永豪 对统计出现的问题进一步完善 学习将项目做成APK 郑靖涛 完善报表设计 协助设计账目一览表板块 杨海亮 测 ...

  5. Java第十三周总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

  6. Java图的邻接矩阵实现

    /** * * 图的邻接矩阵实现 * @author John * * @param <T> */ class AMWGraph<T> { private ArrayList& ...

  7. 轻松把你的项目升级到PWA

    什么是PWA PWA(Progressive Web Apps,渐进式网页应用)是Google在2015年推出的项目,致力于通过web app获得类似native app体验的网站. 优点 1.无需客 ...

  8. [android游戏开发初学]简单的游戏框架

    这两天,没事想学习游戏开发,看了一些资料之后准备开始.为了将来编码方便,先写了一个简单的游戏框架方便自己以后做练习用. 如果以后没有什么特殊的需求--比如opengl什么的,会尽量用这个简单框架来实现 ...

  9. 《JavaScript闯关记》视频版硬广

    <JavaScript闯关记>视频版硬广 stone 在菜航工作时,兼任内部培训讲师,主要负责 JavaScript 基础培训,2016年整理的<JavaScript闯关记>课 ...

  10. 支持向量机SVM(Support Vector Machine)

    支持向量机(Support Vector Machine)是一种监督式的机器学习方法(supervised machine learning),一般用于二类问题(binary classificati ...