C# 通过套接字进行序列化,一个类被序列化,另一个则没有

发布于 2024-11-03 09:38:34 字数 7706 浏览 5 评论 0原文

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

员工类别(还有奖金)正在序列化,但是当我尝试传递给 formater 是一个 Transfer 实例,

formatter.Serialize(stream, transferObj);

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

sendToServer()

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

im am trying to make for a school project a client-server application in C#
My problem is that one class gets serialized ok and is sent over the socket, and the other is not and i cant figure it out.

Employee class (and also Bonus) is getting serialized, but when i try to pass to
the formater a Transfer instance

formatter.Serialize(stream, transferObj);

it throws exception: NotSupportedException
with message: Memory stream is not expandable.

sendToServer()

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

Employee Class

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
}

}

Transfer Class

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

Bonjour°[大白 2024-11-10 09:38:34

它不允许您这样做,因为您使用固定长度字节数组显式初始化 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();

It doesn't let you because you explicitly initialize the MemoryStream with a fixed length byte array. See this: http://weblogs.asp.net/ashicmahtab/archive/2008/08/25/memorystream-not-expandable-invalid-operation-exception.aspx

Try something like this instead:

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


            formatter.Serialize(stream, e);
            byte[] buffer = ((MemoryStream)stream).ToArray();
〆凄凉。 2024-11-10 09:38:34

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

Stream stream = new MemoryStream();

请参阅此博客条目< /a>

By providing a buffer to the MemoryStream constructor you are fixing it to that size. If you just use the default constructor, the stream should be expandable to whatever size is required.

Stream stream = new MemoryStream();

See this blog entry

悸初 2024-11-10 09:38:34

设置更大的缓冲区将让我序列化 Transfer 类

setting a larger buffer will let me serialize Transfer class

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文