【问题标题】:Type 'System.Net.Sockets.Socket' cannot be serialized类型“System.Net.Sockets.Socket”无法序列化
【发布时间】:2012-07-11 11:56:54
【问题描述】:

类型“System.Net.Sockets.Socket”无法序列化。考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。

我正在 WCF 中创建一项服务,该服务打开连接并向服务器发送消息,但是当我运行该服务时出现上述错误。我不知道如何用数据契约属性标记它或如何解决问题。

public class Service1 : IService1
{


    public void Connect(String a , String b)
    {

        int hit = Convert.ToInt32(a);

        int delay = Convert.ToInt32(b);
        delay = delay * 1000; 

 // I have eliminated the log making part       string LogPath = "C:\\VoltTestApp\\Logs\\";


        for (int i = 1; i <= hit; i++)
        {

            try
            {
                TcpClient tcpClient = new TcpClient("10.111.13.72", 80);
                Console.WriteLine("Initialized Socket  .............\n");
                Socket socket = tcpClient.Client;
                string str = "ID_T$";

                try
                { // sends the text with timeout 10s
                    Console.WriteLine("Going To Send Request  .............\n");
                    Send(socket, Encoding.UTF8.GetBytes(str.Trim()), 0, str.Length, 10000);
               }


                socket.Close();
                tcpClient.Close();
                Console.WriteLine("Socket Closed  .............\n");
            }

            Thread.Sleep(delay);
        }

    }



    public  void Send(Socket socket, byte[] buffer, int offset, int size, int timeout)
    {
        try
        {
            int startTickCount = Environment.TickCount;
            int sent = 0;  // how many bytes is already sent
            do
            {
                if (Environment.TickCount > startTickCount + timeout)
                    throw new Exception("Timeout.");
                try
                {
                    sent += socket.Send(buffer, offset + sent, size - sent, SocketFlags.None);
                }
                catch (SocketException ex)
                {
                    if (ex.SocketErrorCode == SocketError.WouldBlock ||
                        ex.SocketErrorCode == SocketError.IOPending ||
                        ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
                    {
                        // socket buffer is probably full, wait and try again
                        Thread.Sleep(30);
                    }
                    else
                        throw ex;  // any serious error occurr
                }
            } while (sent < size);
        }

    }

【问题讨论】:

  • 如果没有相关代码,我们无法为您提供帮助。但建议不要尝试将实际的套接字作为消息发送。
  • 提供一些代码。不要认为序列化 Socket 在这里是正确的..
  • 因此,如果我消除发送功能并简单地在连接功能中执行该部分,以便我的方法不采用套接字参数,它会工作吗?或者什么是可能的解决方案,因为它是我的第一个 wcf 应用程序
  • 进一步查看我的答案 - 如果您不在其他任何地方使用发送,请将其设为私有。 =)

标签: c# asp.net wcf sockets


【解决方案1】:

在这种情况下,这可能是因为您的服务上有一个公共方法,该方法将 Socket 作为参数。这很自然地在尝试服务发现时无法正确序列化。

如果Send只在内部使用,设置为私有。

【讨论】:

    【解决方案2】:

    您无法明智地在对 wcf 服务的调用之间保持 tcp 连接。在你的情况下 我将从服务合同中删除 Connect 方法,在您的 Service1 类中将其更改为私有, 从您的发送方法中删除套接字参数(在 IService1 及其在 Service1 类中的实现中) 并从您的发送方法调用您的连接方法(以便每次发送都连接和断开连接)

    【讨论】:

    • 但是你的解决方案能解决不能让套接字序列化的问题吗?而且我不能序列化套接字,然后我不能将它们与 WCF 一起使用,这是我到目前为止所学到的
    • 不,我是在假设您正在尝试做什么(因为它并不明显)。您绝对不能序列化套接字 - 它们代表/包装 2 个网络节点之间的开放网络连接。在我看来(我假设)您正在尝试使用 WCF 服务来简化(从客户端应用程序的角度)与 tcp 服务器的通信 - 即,您希望您的客户端应用程序只处理 WCF 而不是 tcp 套接字本身.这不是你想要做的吗?
    【解决方案3】:

    错误信息具有误导性,解决方法是不要在System.Net.Sockets.Socket 中添加DataContractAttribute。问题是您无法通过网络发送套接字。更具体地说,您不能对其进行序列化,并且要发送它,您必须能够对其进行序列化。

    您需要找到一个不涉及通过网络发送套接字(或将其保存到磁盘/数据库)的解决方案。

    【讨论】:

    • 我确实发现尝试保存套接字以供以后相当有趣的前景。 =)
    • 所以你建议我重新构建我的解决方案。我实际上有一个 Web 表单,它将某些数据发送到服务,然后服务将连接到非本地服务器(我目前只关注客户端部分,所以如果我不能使用,你如何建议我将我的服务连接到主机插座
    猜你喜欢
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    相关资源
    最近更新 更多