代码之家  ›  专栏  ›  技术社区  ›  alansiqueira27

套接字和序列化C出现问题#

  •  0
  • alansiqueira27  · 技术社区  · 14 年前

    当我只想将一个字符串从客户机传递到服务器时,它就起作用了。但是我想传递一个对象,它会抛出这个错误:

    代码如下:


    客户:

    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); 
    

    另一个问题:我从客户机复制了class命令并粘贴到服务器进行反序列化。是这样吗?

    谢谢你

    6 回复  |  直到 14 年前
        1
  •  2
  •   Stephen Cleary    14 年前
        2
  •  2
  •   Grzenio    14 年前

    你从不使用从流中读取的消息。因此,您正在读取的内存流是空的。

        3
  •  1
  •   Randolpho    14 年前

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

    clientStream 进入 memoryStream 在从 . 或者,使用 直接而不是使用 内存流 ; 这可能需要重新考虑您的协议。

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

        4
  •  0
  •   feroze    14 年前

    如果将服务器代码更改为使用不同的MemoryStream构造函数,问题就会消失。

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

    不过,我同意斯蒂芬和其他人的看法。要么使用WCF,要么使用消息帧。

        5
  •  0
  •   jp2code    14 年前

    另一个问题:我从客户机复制了class命令并粘贴到服务器进行反序列化。是这样吗?

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

    客户:

    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;
    }
    

        6
  •  0
  •   Syed Waqas    12 年前

    您应该传递'message',因为它是实际的字节流,而不是将bytesRead传递给MemoryStream,MemoryStream实际上是字节流的长度。比如,

    MemoryStream memoryStream = new MemoryStream(message);
    

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

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