各位高手,请帮忙分析一下代码问题出在哪?感谢万分!!!

useruse 2011-08-17 02:01:45


/// <summary>
/// 数据封包
/// </summary>
public class Message
{
private byte _class;
private byte _flag;
private int _size;
private byte[] _content;

public byte[] Content
{
get { return _content; }
set { _content = value; }
}

public int Size
{
get { return _size; }
set { _size = value; }
}

public byte Flag
{
get { return _flag; }
set { _flag = value; }
}

public byte Class
{
get { return _class; }
set { _class = value; }
}
public Message()
{

}

public Message(byte @class, byte flag, byte[] content)
{
_class = @class;
_flag = flag;
_size = content.Length;
_content = content;
}

public byte[] ToBytes()
{
byte[] _byte;
using (MemoryStream mem = new MemoryStream())
{
BinaryWriter writer = new BinaryWriter(mem);
writer.Write(_class);
writer.Write(_flag);
writer.Write(_size);
if (_size > 0)
{
writer.Write(_content);
}
_byte = mem.ToArray();
writer.Close();
}
return _byte;
}

public static Message FromBytes(byte[] Buffer)
{
Message message = new Message();
using (MemoryStream mem = new MemoryStream(Buffer))
{
BinaryReader reader = new BinaryReader(mem);
message._class = reader.ReadByte();
message._flag = reader.ReadByte();
message._size = reader.ReadInt32();
if (message._size > 0)
{
message._content = reader.ReadBytes(message._size);
}
reader.Close();
}
return message;
}

}

/// <summary>
/// 数据包写入流并校验完整性
/// </summary>
public class MessageStream
{
private byte[] _buffer;
private int _position;
private int _length;
private int _capacity;

public MessageStream()
{
_buffer = new byte[0];
_position = 0;
_length = 0;
_capacity = 0;
}

private byte ReadByte()
{
if (this._position >= this._length)
{
return 0;
}
return this._buffer[this._position++];
}

private int ReadInt()
{
int num = this._position += 4;
if (num > this._length)
{
this._position = this._length;
return -1;
}
return (((this._buffer[num - 4] | (this._buffer[num - 3] << 8)) | (this._buffer[num - 2] << 0x10)) | (this._buffer[num - 1] << 0x18));
}

private byte[] ReadBytes(int count)
{
int num = this._length - this._position;
if (num > count)
{
num = count;
}
if (num <= 0)
{
return null;
}
byte[] buffer = new byte[num];
if (num <= 8)
{
int num2 = num;
while (--num2 >= 0)
{
buffer[num2] = this._buffer[this._position + num2];
}
}
else
{
Buffer.BlockCopy(this._buffer, this._position, buffer, 0, num);
}
this._position += num;
return buffer;
}

public bool Read(out Message message)
{
message = null;
_position = 0;
if (_length > 6)
{
message = new Message();
message.Class = ReadByte();
message.Flag = ReadByte();
message.Size = ReadInt();
if (message.Size <= 0 || message.Size <= _length - _position)
{
if (message.Size > 0)
{
message.Content = ReadBytes(message.Size);
Remove(message.Size + 6);
}
else
{
Remove(-message.Size + 6);
}
return true;
}
else
{
message = null;
return false;
}
}
else
{
return false;
}
}

private void EnsureCapacity(int value)
{
if (value <= this._capacity)
return;
int num1 = value;
if (num1 < 0x100)
num1 = 0x100;
if (num1 < (this._capacity * 2))
num1 = this._capacity * 2;
byte[] buffer1 = new byte[num1];
if (this._length > 0)
Buffer.BlockCopy(this._buffer, 0, buffer1, 0, this._length);
this._buffer = buffer1;
this._capacity = num1;
}

public void Write(byte[] buffer, int offset, int count)
{
if (buffer.Length - offset < count)
{
count = buffer.Length - offset;
}
//EnsureCapacity(buffer.Length + count);
//下面正确
EnsureCapacity(_length + count);
Array.Clear(_buffer, _length, _capacity - _length);
Buffer.BlockCopy(buffer, offset, _buffer, _length, count);
_length += count;
}

private void Remove(int count)
{
if (_length >= count)
{
//Buffer.BlockCopy(_buffer, count, _buffer, 0, _length - count);
Buffer.BlockCopy(_buffer, 0, _buffer, 0, _length - count);
//Buffer.BlockCopy(_buffer, count, _buffer, 0, _length);
_length -= count;
Array.Clear(_buffer, _length, _capacity - _length);
}
else
{
_length = 0;
Array.Clear(_buffer, 0, _capacity);
}
}
}

MessageStream msgms = new MessageStream();
msgms.Write(userobject.ReceiveBuffer, 0, buffer.Length);
Message message = new Message();
while (msgms.Read(out message))
{}
//这里输出信息



最后出现:无法附加到崩溃的进程。存储空间不足,无法处理此命令
...全文
194 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
gomoku 2011-08-17
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 useruse 的回复:]
按照您说的,错误日志内容是:

详细内容: System.OutOfMemoryException: 引发类型为“System.OutOfMemoryException”的异常。
在 System.Threading.Thread.StartInternal(IPrincipal principal, StackCrawlMark& stackMark)
在 System.……
[/Quote]

是运行一次就异常,还是运行一段时候后异常?
下面一行的num1一般会达到多大?
byte[] buffer1 = new byte[num1];

心灵彩虹 2011-08-17
  • 打赏
  • 举报
回复
thReseive.Priority = ThreadPriority.Highest;
改成ThreadPriority.Lowest试试
useruse 2011-08-17
  • 打赏
  • 举报
回复
拜求解决方案!!!
感谢万分!!!
useruse 2011-08-17
  • 打赏
  • 举报
回复
[DllImport("kernel32.dll")]
private static extern bool SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);
private static void FlushMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
}


我也强制回收内存了,但是还是报上面的错误!我想应该是数组复制和清理这里出了问题,纠结不晓得问题出在哪里!!!
useruse 2011-08-17
  • 打赏
  • 举报
回复
按照您说的,错误日志内容是:

详细内容: System.OutOfMemoryException: 引发类型为“System.OutOfMemoryException”的异常。
在 System.Threading.Thread.StartInternal(IPrincipal principal, StackCrawlMark& stackMark)
在 System.Threading.Thread.Start(StackCrawlMark& stackMark)
在 System.Threading.Thread.Start()
在 frmMain.ReceiveCallBack(IAsyncResult ar) 位置 frmMain.cs:行号 258
在 System.Net.LazyAsyncResult.Complete(IntPtr userToken)
在 System.Net.ContextAwareResult.CompleteCallback(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Net.ContextAwareResult.Complete(IntPtr userToken)
在 System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
在 System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
在 System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)


我这里258行是

//新建线程
ThreadStart tsReseive = new ThreadStart(Reseive);
//实例化新线程
Thread thReseive = new Thread(tsReseive);
thReseive.IsBackground = true;
thReseive.Priority = ThreadPriority.Highest;
thReseive.Start();

里面的
thReseive.Start();



还是不晓得是哪里的问题,老大,指点一下小弟,谢谢!
useruse 2011-08-17
  • 打赏
  • 举报
回复
通过观察,运行程序后内存上升到50多M就不工作了,如果强制回收内存会导致信息丢失了
  • 打赏
  • 举报
回复
这么多代码......唉!

不过你可以捕获并打印造成进程崩溃的具体代码的整个异常堆栈信息。可以在你的主程序的一开始,写类似这样的代码:
var handler = new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
AppDomain.CurrentDomain.UnhandledException += handler;
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Debug.Print("{0}发生系统异常:{1}", DateTime.Now, e.ExceptionObject.ToString());
}
这样,当你在vs中调试时进程直接结束了,你可以打开 Debug->Windows->Output 窗口看看打印的信息,有详细的错误堆栈信息。当然你也可以把它输出到文本文件里观看。
gomoku 2011-08-17
  • 打赏
  • 举报
回复
OutOfMemoryException有可能因为某些bug造成MessageStream没有机会得到垃圾回收。

也有可能是因为内存碎片:
如果MessageStream的buffer1不小,比如超过85k,内存可能被分配到所谓的“大对象堆(Large Object Heap)”,而垃圾回收是不移动大对象堆中的对象的。

因次,当MessageStream不断被创建/销毁,夹杂着其他对象进入到大对象堆,有可能大对象堆出现碎片,以至于要分配比较大块的连续空间时,出现OutOfMemoryException异常。

useruse 2011-08-17
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 gefangliang 的回复:]

thReseive.Priority = ThreadPriority.Highest;
改成ThreadPriority.Lowest试试
[/Quote]

也不行的
useruse 2011-08-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 gomoku 的回复:]

引用 2 楼 useruse 的回复:
按照您说的,错误日志内容是:

详细内容: System.OutOfMemoryException: 引发类型为“System.OutOfMemoryException”的异常。
在 System.Threading.Thread.StartInternal(IPrincipal principal, StackCrawlMark&amp;……
[/Quote]

这里有时候会超过int32的临界值


是每次运行一段时间后,当接受的包达到一定数量后就出问题了

110,502

社区成员

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

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

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