开发者

Broken sockets in .NET?

Here's a really strange problem: Apparently, the specific sequence of bytes which translates to ASCII "PUttttt", if sent over a TCP socket doesn't make it to the client at all.

I've included the sample code used to demonstrate the problem below in hopes that someone might have an idea as to why this is happening. The server and client applications have been intentionally reduced to simple console synchronous versions to make troubleshooting easier.

The key aspect of the problem is the data that goes into the send buffer (the开发者_运维百科 "PUttttt" string).

The server:

using System;      
using System.Net.Sockets;
using System.Net;

namespace ConsoleServer
{
    private static Socket mServer;
    private static byte[] fileBytes;
    private static int sent_total;

    static void Main(string[] args)
    {
        string hostName = "localhost";  //Dns.GetHostName();
        IPHostEntry ipHostInfo = Dns.GetHostEntry(hostName);
        IPAddress iaddr = null;
        for(int k = 0; k < ipHostInfo.AddressList.Length; k++)
            if (ipHostInfo.AddressList[k].AddressFamily == AddressFamily.InterNetwork)
            {
                iaddr = ipHostInfo.AddressList[k];
                break;
            }

        if (iaddr == null)
        {
            Console.WriteLine("Can not bind to any interface.. Server can not start");
            Console.ReadKey();
            return;
        }

        mServer = new Socket(iaddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        mServer.Bind(new IPEndPoint(iaddr, 8000));

        Console.WriteLine("Server: Bound to " + hostName + " (" + iaddr.ToString() + "):8000");
        mServer.Listen(1);

        Console.WriteLine("Server: Started. Awaiting connection.");

        Socket handler = mServer.Accept();
        handler.LingerState = new LingerOption(true, 5);

        Console.WriteLine("Server: A Client connected\r\nServer: sending data");

        string str = @"PUttttt";
        fileBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(str);

        SocketError errCode = SocketError.Success;
        int sent = handler.Send(fileBytes, 0, fileBytes.Length, SocketFlags.None, out errCode);
        sent_total += sent;
        Console.WriteLine("Server: Done sending. " + sent_total + " bytes (" + errCode.ToString() + ")");

        handler.Close();

        Console.WriteLine("Server: CLient Disconnected");

        Console.ReadKey();
    } 
   }
}

The client:

using System;
using System.Net.Sockets;
using System.Net;

namespace ConsoleClient
{
  class Program
  {
    private static int BUFFER_SIZE = 1024 * 1024;
    private static string SERVER_ADDR = "localhost"; //Dns.GetHostName();
    private static int SERVER_PORT = 8000;

    static void Main(string[] args)
    {
        Console.WriteLine("Client: connecting to " + SERVER_ADDR + " server");

        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket.ReceiveTimeout = 30000;
        socket.ReceiveBufferSize = BUFFER_SIZE;
        IPHostEntry ipHostInfo = Dns.GetHostEntry(SERVER_ADDR);

        IPAddress ipAddress = null;
        for (int k = 0; k < ipHostInfo.AddressList.Length; k++)
            if (ipHostInfo.AddressList[k].AddressFamily == AddressFamily.InterNetwork)
            {
                ipAddress = ipHostInfo.AddressList[k];
                break;
            }

        socket.Connect(new IPEndPoint(ipAddress, SERVER_PORT));
        Console.WriteLine("Client: connected");

        byte[] buffer = new byte[BUFFER_SIZE];
        int total = 0;
        int read = socket.Receive(buffer, buffer.Length, SocketFlags.None);
        total += read;

        Console.WriteLine("Client: read " + read + " bytes. " + total + " total");
        while (read > 0)
        {
            try
            {
                read = socket.Receive(buffer, buffer.Length, SocketFlags.None);
                total += read;

                Console.WriteLine("Client: read " + read + " bytes. " + total + " total: ");
            }
            catch (Exception se)
            {
                Console.WriteLine(se.ToString());
                break;
            }
        }

        Console.WriteLine("Client: received " + total + " bytes");

        socket.Shutdown(SocketShutdown.Both);
        socket.Close();

        Console.WriteLine("Connection Closed.");

        Console.ReadKey();
    }
  }
}

I've compiled this using Visual Studio 2010, and the .NET 4 Client Profile but I suspect it is broken in other versions of .NET.

Here's the output from the server:

Server: Bound to localhost (127.0.0.1):8000
Server: Started. Awaiting connection.
Server: A Client connected
Server: sending data
Server: Done sending. 7 bytes (Success)
Server: CLient Disconnected

And this is the output from the client

Client: connecting to localhost server
Client: connected
Client: read 0 bytes. 0 total
Client: received 0 bytes
Connection Closed.

Note the difference between what is sent from the server and what is received by the client. Also, if the line that closes the socket on the server is commented out, the client will just hang waiting to receive data.


It does seem unlikely, but I can confirm this issue: I tried running it with Kaspersky Anti-Virus turned ON. But, when I turned it off it works fine.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜