NetWorkStream.Read() 的问题 。

dota3c 2014-03-11 09:39:00
我写了C/S的抓包程序,大概工作机制是这样的:服务器端不停的将抓到数据包的包头提取出来,刚好是61个字节,用TCP协议发送给客户端,客户端用61个字节的缓存去读,为什么有时候读取的字节数不是61呢?(大多数时候是正常的)。

服务器端采用异地发送方式:

byte[] buffer=new byte[61];
//....将抓到包头放进去
ns.BeginWrite(buffer,0,buffer.Length,sendCallBack,this);

客户端的代码是:

byte[] buffer=new byte[61];
int numOfBytesRead=ns.Read(buffer,0,buffer.Length);
if(numOfBytesRead==61)
{
//有时候会出现numOfBytesRead=16 ,26的情况
//分析这个数据包,

}


这是为什么呢?
...全文
727 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
MikeCheers 2014-03-17
  • 打赏
  • 举报
回复
引用 11 楼 lifang123456 的回复:
,c#好像没有指定接受的大小.......... 先收到,再慢慢循环解包,要分段解包,因为有半包,粘包情况
可以指定你一次最多接收的大小,就是
byte[] buffer=new byte[61];
中的61,但实际接收到多少,要看stream实际收到了多少,大于等于61,就给你61个,小于,就收到多少给多少。
我爱大家369 2014-03-16
  • 打赏
  • 举报
回复
,c#好像没有指定接受的大小.......... 先收到,再慢慢循环解包,要分段解包,因为有半包,粘包情况
MikeCheers 2014-03-15
  • 打赏
  • 举报
回复
另外 对于NetworkStream这个特定的Stream 它是由DataAvailable属性可供使用的
dota3c 2014-03-12
  • 打赏
  • 举报
回复
引用 6 楼 mikecheers 的回复:
建议你还是建立一个大一点的缓冲区 如果发来的数据正好是粘包 你这个代码是要丢掉数据的 搜一下 原来经常看到的可充用缓冲区
我这是个循环读的呀,剩下的数据下一次读就可以了吧,应该不会丢吧
MikeCheers 2014-03-12
  • 打赏
  • 举报
回复
建议你还是建立一个大一点的缓冲区 如果发来的数据正好是粘包 你这个代码是要丢掉数据的 搜一下 原来经常看到的可充用缓冲区
MikeCheers 2014-03-12
  • 打赏
  • 举报
回复
哦 我理解你的意思了 你是说外面还会有个循环机制
引用 7 楼 dota3c 的回复:
... 我这是个循环读的呀,剩下的数据下一次读就可以了吧,应该不会丢吧
理论上可以, 但你要保证ns一直有效
MikeCheers 2014-03-12
  • 打赏
  • 举报
回复

byte[] buffer=new byte[61];
int numOfBytesRead=0;
while(numOfBytesRead!=61)
{
    numOfBytesRead+=ns.Read(buffer,numOfBytesRead,buffer.Length-numOfBytesRead);
}
再审审上边的代码, 当numOfBytesRead==61, 你的循环就退出了. 如果ns里还有数据,是不是丢了?
dota3c 2014-03-11
  • 打赏
  • 举报
回复
嘿嘿,我自己想到了个办法,可以这么做:
byte[] buffer=new byte[61];
int numOfBytesRead=0;
while(numOfBytesRead!=61)
{
    numOfBytesRead+=ns.Read(buffer,numOfBytesRead,buffer.Length-numOfBytesRead);
}
本拉灯 2014-03-11
  • 打赏
  • 举报
回复
TCP做不到,要么自己建缓冲驱,没达到61字节,不放出去, 之前我给人回的贴子 http://bbs.csdn.net/topics/390316188 看这个,自己改一下
dota3c 2014-03-11
  • 打赏
  • 举报
回复
引用 1 楼 wyd1520 的回复:
这正常呀,TCP会把数据包分成多个包分开发,所以有时你收到的是16,而有时会把两个包粘在一起,一起发过来。
我需要61个字节,61个字节的读,该怎么做呢?
本拉灯 2014-03-11
  • 打赏
  • 举报
回复
这正常呀,TCP会把数据包分成多个包分开发,所以有时你收到的是16,而有时会把两个包粘在一起,一起发过来。
using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets; using System.Collections; using System.IO; using System.Text.RegularExpressions; using RE = System.Text.RegularExpressions.Regex; using System.Security.Cryptography.X509Certificates; /*************************************************************************************************************************************************** * *文件名:HttpProc.cs * *创建人:HeDaode * *日 期:2007.09.01 * *描 述:实现HTTP协议中的GET、POST请求 * *使 用:HttpProc.WebClient client = new HttpProc.WebClient(); client.Encoding = System.Text.Encoding.Default;//默认编码方式,根据需要设置其他类型 client.OpenRead("http://www.baidu.com");//普通get请求 MessageBox.Show(client.RespHtml);//获取返回的网页源代码 client.DownloadFile("http://www.codepub.com/upload/163album.rar",@"C:\163album.rar");//下载文件 client.OpenRead("http://passport.baidu.com/?login","username=zhangsan&password=123456");//提交表单,此处是登录百度的示例 client.UploadFile("http://hiup.baidu.com/zhangsan/upload", @"file1=D:\1.mp3");//上传文件 client.UploadFile("http://hiup.baidu.com/zhangsan/upload", "folder=myfolder&size=4003550",@"file1=D:\1.mp3");//提交含文本域和文件域的表单 *****************************************************************************************************************************************************/ namespace HttpProc { /// ///上传事件委托 /// /// /// public delegate void WebClientUploadEvent(object sender, HttpProc.UploadEventArgs e); /// ///下载事件委托 /// /// /// public delegate void WebClientDownloadEvent(object sender, HttpProc.DownloadEventArgs e); /// ///上传事件参数 /// public struct UploadEventArgs { /// ///上传数据总大小 ///

110,500

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧