2

我正在尝试为学校项目制作 C# 中的客户端-服务器应用程序我的问题是一个类可以序列化并通过套接字发送,而另一个不是,我无法弄清楚。

Employee 类(以及 Bonus)正在被序列化,但是当我尝试将一个 Transfer 实例传递给格式化程序时

formatter.Serialize(stream, transferObj);

它抛出异常:NotSupportedException 并带有消息:内存流不可扩展。

发送到服务器()

 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        System.Net.IPAddress ipAdd = System.Net.IPAddress.Parse("127.0.0.1");
        System.Net.IPEndPoint remoteEP = new IPEndPoint(ipAdd, 6666);
        socket.Connect("127.0.0.1", 6666);


        Transfer t = new Transfer();

        Employee e = new Employee(); 
        Bonus b = new Bonus(); b.setAmmount(234); b.setDescription("xxxx");
        e.getBonuses().Add(b);

        byte[] buffer = new byte[1000];
        System.Console.WriteLine("client started");

            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream(buffer);


            formatter.Serialize(stream, e);
             // Employee and Bonus are serialized but not Transfer
            stream.Flush();

            socket.Send(buffer,buffer.Length,0);

员工类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Permissions;
using System.Runtime.Serialization;

namespace Entity
{
[Serializable]
public class Employee : ISerializable
{

    private int id;
    private long version;
    private String username;
    private String password;
    private String role;
    private String name;
    private String surname;
    private long salary;
    private DateTime experience;
    private DateTime birthDate;
    private String sex;
    private List<Bonus> bonuses;

    public Employee() {
        bonuses = new List<Bonus>();
    }

       protected Employee(SerializationInfo info, StreamingContext context)
    {
        id = info.GetInt32("id");
        version = info.GetInt32("version");
        username = info.GetString("username");
        password = info.GetString("password");
        role = info.GetString("role");
        name = info.GetString("name");
        surname = info.GetString("surname");
        salary = info.GetInt32("salary");
        experience = (DateTime) info.GetValue("exp", typeof(DateTime));
        birthDate = (DateTime)info.GetValue("birth", typeof(DateTime));
        sex = info.GetString("sex");
        bonuses = (List<Bonus>) info.GetValue("bonuses", typeof(List<Bonus>));

    }





    public int getId()
    {
        return id;
    }
    public void setId(int id)
    {
        this.id = id;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public String getSurname()
    {
        return surname;
    }
    public void setSurname(String surname)
    {
        this.surname = surname;
    }
    public long getSalary()
    {
        return salary;
    }
    public void setSalary(long salary)
    {
        this.salary = salary;
    }
    public DateTime getExperience()
    {
        return experience;
    }
    public void setExperience(DateTime experience)
    {
        this.experience = experience;
    }
    public DateTime getBirthDate()
    {
        return birthDate;
    }
    public void setBirthDate(DateTime birthDate)
    {
        this.birthDate = birthDate;
    }
    public List<Bonus> getBonuses()
    {
        return bonuses;
    }
    public void setBonuses(List<Bonus> bonuses)
    {
        this.bonuses = bonuses;
    }


    public override string ToString()
    {
        return name + " " + surname;
    }

    public override int GetHashCode()
    {
        int prime = 31;
        int result = 1;
        result = prime * result + id;
        return result;
    }

    public override bool Equals(System.Object obj)
    {
        // If parameter is null return false.
        if (obj == null)
        {
            return false;
        }

        // If parameter cannot be cast to Point return false.
        Employee p = obj as Employee;
        if ((System.Object)p == null)
        {
            return false;
        }

        // Return true if the fields match:
        return id == p.id;
    }

    public void setSex(String sex)
    {
        this.sex = sex;
    }
    public String getSex()
    {
        return sex;
    }
    public long getVersion()
    {
        return version;
    }
    public void setVersion(long version)
    {
        this.version = version;
    }
    public String getUsername()
    {
        return username;
    }
    public void setUsername(String username)
    {
        this.username = username;
    }
    public String getPassword()
    {
        return password;
    }
    public void setPassword(String password)
    {
        this.password = password;
    }
    public String getRole()
    {
        return role;
    }
    public void setRole(String role)
    {
        this.role = role;
    }

    #region ISerializable Members
    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("id", id);
        info.AddValue("version", version);
        info.AddValue("username", username);
        info.AddValue("password", password);
        info.AddValue("role", role);
        info.AddValue("name", name);
        info.AddValue("surname", surname);
        info.AddValue("salary", salary);
        info.AddValue("exp", experience);
        info.AddValue("birth", birthDate);
        info.AddValue("sex", sex);
        info.AddValue("bonuses", bonuses);
    }

    #endregion
}

}

转学班

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Permissions;
using System.Runtime.Serialization;


namespace Entity
{
[Serializable]
public class Transfer : ISerializable
{
    private Employee employee;
    private String method;
    private String message;
    private List<Employee> queriedEmployees;

    public Transfer() {
        queriedEmployees = new List<Employee>();
    }

    protected Transfer(SerializationInfo info, StreamingContext context)
    {

        employee = (Employee) info.GetValue("employee", typeof(Employee) );
        method = info.GetString("method");
        message = info.GetString("message");
        queriedEmployees = (List<Employee>) info.GetValue("qe", typeof(List<Employee>));
    }






    public Employee getEmployee() 
    {
        return employee;
    }

    public String getMethod()
    {
        return method;
    }

    public String getMessage()
    {
        return message;
    }

    public List<Employee> getQueriedEmployees()
    {
        return queriedEmployees;
    }

    public void setEmployee(Employee e)
    {
        employee = e;
    }

    public void setMessage(String mes)
    {
        message = mes;
    }

    public void setMethod(String meth)
    {
        method = meth;
    }

    public void setQueriedEmployees(List<Employee> elist)
    {
        queriedEmployees = elist;
    }



    #region ISerializable Members
    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("employee", employee);
        info.AddValue("method", method);
        info.AddValue("message", message);
        info.AddValue("qe", queriedEmployees);
    }

    #endregion
}
}
4

3 回答 3

5

它不会让您这样做,因为您使用固定长度的字节数组显式初始化 MemoryStream。看到这个:http ://weblogs.asp.net/ashicmahtab/archive/2008/08/25/memorystream-not-expandable-invalid-operation-exception.aspx

尝试这样的事情:

            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream();


            formatter.Serialize(stream, e);
            byte[] buffer = ((MemoryStream)stream).ToArray();
于 2011-04-25T17:29:15.057 回答
4

通过为 MemoryStream 构造函数提供一个缓冲区,您可以将其固定为该大小。如果您只使用默认构造函数,则流应该可以扩展到所需的任何大小。

Stream stream = new MemoryStream();

请参阅此博客条目

于 2011-04-25T17:33:12.860 回答
-2

设置一个更大的缓冲区可以让我序列化 Transfer 类

于 2011-04-25T17:21:24.967 回答