繁体   English   中英

套接字和序列化C#问题

[英]Problem with Socket and Serialization C#

我实现了将套接字与线程一起使用的客户端和服务器模型

当我只希望将字符串从客户端传递到服务器时,它可以工作。 但是我想传递一个对象,它将引发此错误:“试图反序列化空流”

这是代码:


客户:

ASCIIEncoding asen = new ASCIIEncoding();

MemoryStream memoryStream = new MemoryStream();
BinaryFormatter binaryFormatter = new BinaryFormatter();
Command command = new Command("meuLogin", "minhaSenha");
binaryFormatter.Serialize(memoryStream, command);

stream.Write(memoryStream.ToArray(), 0, memoryStream.ToArray().Length);

服务器:

byte[] message = new byte[4096];
int bytesRead = 0;
bytesRead = clientStream.Read(message, 0, 4096);

MemoryStream memoryStream = new MemoryStream(bytesRead);
BinaryFormatter bf1 = new BinaryFormatter();
memoryStream.Position = 0;

Command command = (Command)bf1.Deserialize(memoryStream); 

另一个问题:我从客户端复制了Command类,并粘贴到Server上进行反序列化。 这个对吗?

谢谢

您永远不会使用从流中读取的消息。 您正在读取的内存流因此为空。

附带说明一下,为什么要使用这些中间MemoryStream?

我还建议使用WCF。 但是,如果继续使用套接字,则协议中缺少的关键元素是消息框架

回答您的第二个问题:为了获得最大的可维护性, Command类应该在客户端和服务器都引用的单独程序集中。

回答您的第一个问题:您正尝试从服务器上的空流中反序列化,就像异常告诉您的那样。 在从clientStream反序列memoryStream之前,需要将从clientStream读取的字节复制到memoryStream 或者,直接使用clientStream而不是使用memoryStream 这可能需要重新考虑您的协议。

最后,我完全同意@Andrey:考虑使用WCF。 它比原始套接字更好。

而不是将bytesRead传递给实际上是字节流长度的MemoryStream,而应该传递“ message”,因为它是实际的字节流。 喜欢,

MemoryStream memoryStream = new MemoryStream(message);

当您传递整数变量时,编译器将抛出异常,即流为空。

对于WCF,这是一个了不起的框架,但是对于要求低延迟和高性能的应用程序,WCF是基于套接字的,因为它的开销是一个可怕的答案。 因此,如果使用套接字,那将是最低级别的实现,因此也是最快的实现。 这取决于您的应用程序应该选择哪种范式...

如果将服务器代码更改为使用其他MemoryStream构造函数,则问题将消失。

MemoryStream memoryStream = new MemoryStream(message, 0, bytesRead);

但是,我同意斯蒂芬和其他人的看法。 使用WCF或使用消息框架。

另一个问题:我从客户端复制了Command类,并粘贴到Server上进行反序列化。 这个对吗?

否。您的客户端和服务器的名称空间可能不同,因此服务器将尝试反序列化与其名称空间匹配的流。

您应该使用自己的命名空间创建命令类,并从客户端和服务器两者中引用它。

之后...

客户:

static void StreamToServer(TcpClient client, Command obj) {
  using (NetworkStream ns = client.GetStream()) {
    using (MemoryStream ms = new MemoryStream()) {
      BinaryFormatter formatter = new BinaryFormatter();
      formatter.Serialize(ms, obj);
      byte[] buf = ms.ToArray();
      ns.Write(buf, 0, buf.Length);
    }
  }
}

服务器:

static Command ReadStream(TcpListener listener) {
  Command obj = null;
  using (TcpClient client = listener.AcceptTcpClient()) { // waits for data
    using (NetworkStream ns = client.GetStream()) {
      byte[] buf = new byte[client.ReceiveBufferSize];
      int len = ns.Read(buf, 0, buf.Length);
      using (MemoryStream ms = new MemoryStream(buf, 0, len)) {
        BinaryFormatter formatter = new BinaryFormatter();
        obj = formatter.Deserialize(ms) as Command;
      }
    }
  }
  return obj;
}

WCF或消息框架可能更容易,但是我经常没有机会在工作中坐下来阅读一本书。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM