经过断点跟踪发现在这行中:
ntStream.Write(sendBytes, 0, (int) sendStream.Length);
sendStream.Length 的值为 182但是到了这行,却发现:
int bytesRead = stream.Read(bytes, 0, (int) client.ReceiveBufferSize);
byresRead 的值为 176为什么前后两个值有偏差呢?奇怪了,希望大家能够看看,谢谢。
ntStream.Write(sendBytes, 0, (int) sendStream.Length);
sendStream.Length 的值为 182但是到了这行,却发现:
int bytesRead = stream.Read(bytes, 0, (int) client.ReceiveBufferSize);
byresRead 的值为 176为什么前后两个值有偏差呢?奇怪了,希望大家能够看看,谢谢。
解决方案 »
- C#能够把TXT转换为Excel吗?在未安装office的情况下
- 课本这个例子代码解释是不是有错啊?从大到小与从小到大删除索引号结果不一样吗?
- Microsoft Visual Studio 2008中解决方案的问题
- [急!!!]弹出的等待对话框如何实现?
- C++中hwndIE在C#中对应是什么
- 询问数据库连接的问题,以EXCEL文件作为数据库!
- 为何NotifyICON控件上的ContentMenu中的MenuItem在触发时,不能触发MenuItem的MesureItem和DrawItem的事件!各位可以试一试!!欢迎讨论
- 关于截获键盘消息的问题
- webD页面中如何去掉缓存?(结贴王,在线等待)
- 拷贝一个文件,同时显示拷贝进度,是不是要用到多线程??
- 求助关于 删和改!
- 初学通信接口,想用c#来编程序,什么书比较好?
后面有调用Flush吗
没有用哦,以下是 NetworkStream.Flush() 在MSDN中的描述:[b]备注
Flush 方法实现 Stream.Flush 方法,但是因为 NetworkStream 不进行缓冲处理,所以此方法对网络流无效。调用 Flush 方法不会引发异常。[/b]
方法(如果数据较大可以分包发送),给发送的数据包加上头信息,一般我喜欢设的顺序是包长,包个数,第几个包等等
具体的方法你可以去网上查找一下tcpip通讯的分包组包
private TcpClient myTCPclient;
//
//
//发送数据到
public static void Send(string myStr)
{
ArrayList message = new ArrayList();
message.Add(myStr);
//
// 序列化要传送的数据到临时流
//
MemoryStream mStream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
formatter.TypeFormat = FormatterTypeStyle.TypesWhenNeeded;
formatter.Serialize(mStream, message);
mStream.Flush();
//
// 写入流头
//
MemoryStream sendStream = new MemoryStream();
Byte[] buffer;
//
// 写验证标识 (1 字节)
//
buffer = BitConverter.GetBytes(isValidate);
sendStream.Write(buffer, 0, buffer.Length);
//
// 写临时流长度 (4 字节)
//
buffer = BitConverter.GetBytes((int) mStream.Length);
sendStream.Write(buffer, 0, buffer.Length);
//
// 写发送标识 (4 字节)
//
buffer = BitConverter.GetBytes(StreamID ++);
sendStream.Write(buffer, 0, buffer.Length);
//
// 写入临时流到发送流
//
Byte[] mbuffer = mStream.GetBuffer();
sendStream.Write(mbuffer, 0, (int) mStream.Length);
sendStream.Flush(); Byte[] sendBytes = sendStream.GetBuffer();
ntStream.Write(sendBytes, 0, (int) sendStream.Length);
} 以下代码为读出NetworkStream,在收到NetworkStream后,将其反序列化:
//
//将接收到的信息进行再分配处理
//
public static ArrayList ReceiveScheduler(TcpClient client, NetworkStream stream)
{
byte[] bytes = new byte[client.ReceiveBufferSize];
ArrayList message = null; int bytesRead = stream.Read(bytes, 0, (int) client.ReceiveBufferSize); // 提示这行出错。 if (bytesRead > 0)// 图过信息队列中,信息内容不为空,则读出
{
try
{
int sendLength = BitConverter.ToInt32(bytes, 1) + 9; if (sendLength == bytesRead)
{
MemoryStream mStream = new MemoryStream(bytes, 9, sendLength - 9);
BinaryFormatter formatter = new BinaryFormatter();
formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
formatter.TypeFormat = FormatterTypeStyle.TypesWhenNeeded;
message = (ArrayList) formatter.Deserialize(mStream);
message.Add(BitConverter.ToUInt32(bytes, 5));
}
}
catch
{
//
// 忽略
//
}
} return message;
} /////////////////////////////
用的时候
private void button1_Click(object sender, System.EventArgs e)
{
string myStr1 = "aaaaaaa";
Send(myStr1); // 测试用,第一次断点时,放在此处;第二次断点时放再 Send(myStr2)后面;发现两次的 bytesRead 值都一样
byte[] bytes = new byte[myTCPclient.ReceiveBufferSize];
int bytesRead = ntGameServerManagerStream.Read(bytes,0,myTCPclient.ReceiveBufferSize);
ReceiveScheduler(myTCPclient, ntStream); string myStr2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
Send(myStr2);
}
首先将 myStr1 写入ntStream ,然后用函数 ReceiveScheduler(myTCPclient, ntStream) 将 ntStream 读出;然后再向 ntStream 写入 myStr2 ;运行的时候断点发现,两次 bytesRead 的值都是一样的,是不是我第二次写入ntStream的时候没有成功呢?这是什么原因呢?麻烦大家帮忙看看,非常感谢。
Send(myStr1); byte[] bytes = new byte[10240];
int bytesRead = ntGameServerManagerStream.Read(bytes,0,myTCPclient.ReceiveBufferSize);
ReceiveScheduler(myTCPclient, ntStream); string myStr2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
Send(myStr2);
int bytesRead2 = ntGameServerManagerStream.Read(bytes,0,myTCPclient.ReceiveBufferSize);
这样测下,看接收的大小还一样吗?按理说不一样。
因为mStream.GetBuffer()并不是获取的整个内存流的数据,而是内部缓冲区的数据。
public virtual byte[] GetBuffer();返回值
创建此流所用的字节数组;或者如果在当前实例的构造期间没有向 MemoryStream 构造函数提供字节数组,则为基础数组。
ToArray()
将整个流内容写入字节数组,而与 Position 属性无关。[C#]
public virtual byte[] ToArray();返回值
新字节数组。