问题描述
各位大神:C#写的异步客户端的接收回调publicvoidreadCallback(IAsyncResultar){StateObjectstate=(StateObject)ar.AsyncState;Sockethandler=state.WorkSocket;intread=handler.EndReceive(ar);if(read>0){state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,read));handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,newAsyncCallback(readCallback),state);}else{if(state.sb.Length>1){stringcontent=state.sb.ToString();Console.WriteLine("Read{0}bytesfromsocket.nData:{1}",content.Length,content);}}}问题如下:如果服务端发送过来的数据没有自定义的包头和包尾,长度不定,且缓冲区设置小于接收包长度,也就是需要再次或多次读取,怎么保证读取的数据完整和不重复?求思路和方法,多谢指点感激不尽。
解决方案
解决方案二:
自己给自己找麻烦,没有校验信息,只能让老天爷赐予你幸运吧,建议你改传输结构
解决方案三:
引用楼主tianchao123456的回复:
问题如下:如果服务端发送过来的数据没有自定义的包头和包尾,长度不定,且缓冲区设置小于接收包长度,也就是需要再次或多次读取,怎么保证读取的数据完整和不重复?求思路和方法,多谢指点感激不尽。
首先有几个基本的知识错误。缓冲区大小跟接受完整不完整无关。假设对一次Send8k字节内容,而你的缓冲区大小是128k,也完全可能分包啊。谁跟你说分包是因为你的应用程序的接受缓冲区设置的“小”而造成的呢?另一个问题,你的原问题。所谓“发过来的数据”,如果就扔在你面前,请问你怎么识别消息?如果你连“人”都说不出怎么识别的规范,你想靠抄写别人的代码就告诉你如何识别你的数据?那么你这种学习方法也太奇葩了,而且也不会自己设计出任何实际的程序。(可是很多人偏偏就是靠瞎蒙、然后求人给写代码来进程程序设计的,而自己不把道理先说明白)
解决方案四:
对于tcp来说,分包、粘包是最基本的概念,不要拿它来说什么“数据不完整”。你本来就应该学会分包读取数据。tcp保证数据的次序正确,而且也不重复。用不着担心它“重复”。
解决方案五:
TCP粘包解决
解决方案六:
引用1楼bdmh的回复:
自己给自己找麻烦,没有校验信息,只能让老天爷赐予你幸运吧,建议你改传输结构
通过验证问题中的那种结构确实不能正确处理,听人劝,吃饱饭,数据已按照已有协议传送
解决方案七:
引用2楼sp1234的回复:
Quote: 引用楼主tianchao123456的回复:
问题如下:如果服务端发送过来的数据没有自定义的包头和包尾,长度不定,且缓冲区设置小于接收包长度,也就是需要再次或多次读取,怎么保证读取的数据完整和不重复?求思路和方法,多谢指点感激不尽。首先有几个基本的知识错误。缓冲区大小跟接受完整不完整无关。假设对一次Send8k字节内容,而你的缓冲区大小是128k,也完全可能分包啊。谁跟你说分包是因为你的应用程序的接受缓冲区设置的“小”而造成的呢?另一个问题,你的原问题。所谓“发过来的数据”,如果就扔在你面前,请问你怎么识别消息?如果你连“人”都说不出怎么识别的规范,你想靠抄写别人的代码就告诉你如何识别你的数据?那么你这种学习方法也太奇葩了,而且也不会自己设计出任何实际的程序。(可是很多人偏偏就是靠瞎蒙、然后求人给写代码来进程程序设计的,而自己不把道理先说明白)
感谢回复!可能问题表述还是有一些不准确的地方。缓冲区大小跟接受完整不完整无关,这个知识点我还是知道的。之前比较疑惑的是如果客户端发送100字节,服务端缓冲区是20字节,那么readCallback就应该反复被调用直到没有数据,这里应该是取了5次。5次过后程序并没有走if(read>0)else{}的else块,难道是判断不对吗?我的原问题,这位大哥说的很对,我都不知道规范和原数据就想要硬去处理,显然不太现实。一个问题:分包我觉得应该是在客户端进行的,也就是给数据"包'加个“头”和“尾”以便处理?是这样吗?
解决方案八:
引用3楼sp1234的回复:
对于tcp来说,分包、粘包是最基本的概念,不要拿它来说什么“数据不完整”。你本来就应该学会分包读取数据。tcp保证数据的次序正确,而且也不重复。用不着担心它“重复”。
受益匪浅。关于分包和粘包还请不吝赐教!
解决方案九:
一个问题:分包我觉得应该是在客户端进行的跟客户端还是服务端没有关系你接收的时候就必须处理分包问题
解决方案十:
引用8楼Z65443344的回复:
一个问题:分包我觉得应该是在客户端进行的跟客户端还是服务端没有关系你接收的时候就必须处理分包问题
是不是这样理解,分包不是“拆分”而是“分别”,就是接受时每次都对读过来的“包”进行判断,或留或丢弃
解决方案十一:
引用4楼wangjun8868的回复:
TCP粘包解决
学习了粘包的思想是不是就是加头和尾,接收是进行逻辑判断?
解决方案十二:
引用10楼tianchao123456的回复:
Quote: 引用4楼wangjun8868的回复:
TCP粘包解决学习了粘包的思想是不是就是加头和尾,接收是进行逻辑判断?
是这样的