0
votes

Type 'System.Net.Sockets.Socket' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.

I am making a service in WCF which opens connection and send message to server but above error is given when i run the service . I do not know how to mark it with data contract attribute or how to solve the problem.

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

    }
3
Without relevant code, we can impossibly help you. But a suggestion would be not trying to send the actual socket as a message. - J. Steen
provide some code. Don't think serializing Socket is rigth thing to do here.. - Tigran
So if i eliminate the send function and simply do that part in connect function so my method does not take socket parameter , will it work ? or what can be possible solution as it is my first wcf app - user959883
See my answer further down - make Send private if you don't use it anywhere else. =) - J. Steen

3 Answers

1
votes

In this instance, it's probably because you have a public method on your service which takes a Socket as a parameter. This is, quite naturally, not able to be serialized properly when attempting service discovery.

If Send is only used internally, set it as private.

1
votes

You can't sensibly maintain a tcp connection between calls to your wcf service. In your situation I'd remove the Connect method from the service contract, change it to private in your Service1 class, remove the socket parameter from your send method (in both IService1 and its implementation in the Service1 class) and call your connect method from your send method (so that it connects and disconnects for every send)

0
votes

The error message is misleading, the solution is not to add a DataContractAttribute to System.Net.Sockets.Socket. The problem is that you can't send a socket over the network. More specifically you can't serialize it, and to send it you must be able to serialize it.

You'll need to find a solution that doesn't involve sending a socket over a network (or saving it to disk/a database).