C# 套接字问题和OutOfMemory错误
我有个大问题。尝试创建一个应用程序,它必须有两个部分:服务器端和客户端。这两个部分必须以某种方式进行通信并交换对象。我决定使用套接字,因为我不熟悉WCF,我可以在同一台计算机上测试这两个部分(只需将它们放在127.0.0.1地址上进行侦听) 现在,当我试图从客户端发送一些“自定义”可序列化对象时,我在服务器端遇到了“OutOfMemory”异常!我读了一些关于套接字,发送/接收对象的方法,我尝试了一些在网上找到的代码,但没有成功!我不知道我的代码出了什么问题。 这是我的密码: 这是双方代码中定义的测试类:C# 套接字问题和OutOfMemory错误,c#,sockets,networking,C#,Sockets,Networking,我有个大问题。尝试创建一个应用程序,它必须有两个部分:服务器端和客户端。这两个部分必须以某种方式进行通信并交换对象。我决定使用套接字,因为我不熟悉WCF,我可以在同一台计算机上测试这两个部分(只需将它们放在127.0.0.1地址上进行侦听) 现在,当我试图从客户端发送一些“自定义”可序列化对象时,我在服务器端遇到了“OutOfMemory”异常!我读了一些关于套接字,发送/接收对象的方法,我尝试了一些在网上找到的代码,但没有成功!我不知道我的代码出了什么问题。 这是我的密码: 这是双方代码中定义
[Serializable]
class MyClass
{
public string msg="default";
}
客户端发送代码(工作正常):
服务器端代码(导致问题的代码):
所以,我在尝试反序列化时遇到了异常。我不知道怎么了
我威胁我的代码“如果你继续造成问题,我会向StackOverflow的家伙报告你”,所以我在这里:)那里有一些非常奇怪的代码:
- 假设我们未经检查就读取1024字节
- 复制1024个缓冲区
- 假定序列化数据为1024字节,不多不少
- 从中反序列化
我认为这是你的错误;您应该从流中读取正确的字节数(通常在循环中)。通常,您会循环,检查读取的返回值,直到我们读取了所需的数据量,或者我们首先得到EOF(返回),虽然我不确定这是否是问题的直接原因,但您的读取逻辑存在严重问题
MemoryStream
中。与其这样做,不如获取获取缓冲区的MemoryStream
构造函数的重载。这样就不会复制数据EndReceive
;虽然这实际上可能不会导致错误,但这并不符合Begin
/End
旧式异步模式的精神。您应该在回调开始时调用EndXXX
NetTcpBinding
提供了一个基于TCP的绑定,它可以支持长寿命的连接和会话(我就是这么使用它的),甚至可以通过可靠的会话处理保持活动消息以保持连接的打开状态。只需打开一个标志即可。如果您需要更具互操作性的东西(意味着跨平台),您可以编写自己的绑定来执行此操作,并保持代码不变
请看一些TCP WCF示例;您不需要花费很长时间就可以启动并运行某些功能,一旦达到了这一点,修改就很简单,只需在接口中添加一个函数,然后在服务类中添加一个相应的函数。您是否查看了数据?内存中有什么?buffer.length的值是多少?等等@Richard是最后一个-一个残酷强制的1024;但这并不反映实际的数据长度:)@Marc Doh!是的。我没有仔细阅读代码,但试图指出一些基本的调试技术和信息,这些技术和信息可能会指向他的问题根源。@Richard绝对:)教一个人钓鱼等等,我从来没有编程过sockets,很少使用流,所以整个事情对我来说很混乱:\@guest86:如果你还没有编程套接字,那么这更像是使用WCF的信号。
private void cmdSendData_Click(object sender, System.EventArgs e)
{
try
{
MyClass test = new MyClass();
NetworkStream ns = new NetworkStream(m_socWorker); //m_socWorker is socket
BinaryWriter bw = new BinaryWriter(ns);
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, test);
bw.Write(ms.ToArray());
MessageBox.Show("Length is: " + ms.ToArray().Length); //length is 152!
ns.Close();
}
catch(System.Net.Sockets.SocketException se)
{
MessageBox.Show (se.Message );
}
}
public void OnDataReceived(IAsyncResult asyn)
{
try
{
CSocketPacket theSockId = (CSocketPacket)asyn.AsyncState ;
NetworkStream ns = new NetworkStream(m_socWorker);
byte[] buffer = new byte[1024];
ns.Read(buffer, 0, buffer.Length);
BinaryFormatter bin = new BinaryFormatter();
MemoryStream mem = new MemoryStream(buffer.Length);
mem.Write(buffer, 0, buffer.Length);
mem.Seek(0, SeekOrigin.Begin);
MyClass tst = (MyClass)bin.Deserialize(mem); //ERROR IS THROWN HERE!
MessageBox.Show(tst.msg);
theSockId.thisSocket.EndReceive(asyn);
WaitForData(m_socWorker);
}
catch (ObjectDisposedException )
{
System.Diagnostics.Debugger.Log(0,"1","\nOnDataReceived: Socket has been closed\n");
}
catch(SocketException se)
{
MessageBox.Show (se.Message );
}
}