如何使用套接字侦听器类解决性能问题?

本文关键字:性能 问题 解决 何使用 套接字 侦听器 | 更新日期: 2023-09-27 18:12:15

我是TCP/IP编程新手。我使用微软文档和我在网上找到的一个示例创建了一个侦听器。

我已经创建了一个程序,该程序使用本地IP侦听端口。

当消息最终进入时,程序立即达到100%加载并停留在那里,不幸的是我不知道停止它的方法。我假设我必须使用ManualResetEvent,但当我试图实现这一点,网页只是不加载。

我的实现如下:(端口是一个随机端口,如果有人想知道)

public static class Listener 
{
    private const int bufferSize = 2048;
    private static byte[] buffer = new byte[bufferSize];
    private static Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    public static void StartListening()
    {
        //Gets local machine IP address
        string ip = GetLocalIPAddress();
        //Creates the IPADDRESS
        IPAddress ipAddress = IPAddress.Parse(ip);
        //Creates a local end point for .Bind(xxx)
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 1322);
        Socket listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        try
        {
            //Binds to local machines IP with port 1322
            listener.Bind(localEndPoint);
            //Places socket in a listening state
            listener.Listen(0);
            listener.BeginAccept(new AsyncCallback(AcceptCallback), null);

        }
        catch (Exception e)
        {
            //Throw exception
        }
    }
    private static void CloseSocket()
    {
        listener.Shutdown(SocketShutdown.Both);
        listener.Close();
    }
    public static void AcceptCallback(IAsyncResult ar)
    {

        //Socket casted to async state
        Socket listenerSocket = (Socket)ar.AsyncState;
        try
        {
            //Try end accept
            listenerSocket = listener.EndAccept(ar);
        }catch(Exception e)
        {
            //Throw exception
        }
        //Receive data
        listenerSocket.BeginReceive(buffer, 0, bufferSize, SocketFlags.None, new AsyncCallback(ReadCallBack), listenerSocket);
        listener.BeginAccept(new AsyncCallback(AcceptCallback), null); 
    }
    public static void ReadCallBack(IAsyncResult ar)
    {
        Socket listenerSocket = (Socket)ar.AsyncState;
        int received = 0;
        try
        {
            //Amount of bytes that has been sent
            received = listenerSocket.EndReceive(ar);
        }catch(Exception e)
        {
            listener.Close();
        }
        //Create byte array for encoding
        byte[] bytes = new Byte[received];
        Array.Copy(buffer,bytes,received);
        string recievedMessage = Encoding.ASCII.GetString(bytes);
        if (received > 0)
        {
            //do task input
            System.Diagnostics.Debug.WriteLine(recievedMessage);
        }
        //work on this
        listenerSocket.BeginReceive(buffer, 0 , bufferSize, SocketFlags.None, new AsyncCallback(ReadCallBack), listenerSocket);

    }
    private static string GetLocalIPAddress()
    {
        var host = Dns.GetHostEntry(Dns.GetHostName());
        foreach (var ip in host.AddressList)
        {
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            {
                return ip.ToString();
            }
        }
        throw new Exception("Local IP Address Not Found!");
    }

谢谢你的帮助

如何使用套接字侦听器类解决性能问题?

一些问题

  1. 你没有将监听器套接字传递给BeginAccept。

    listener.BeginAccept(new AsyncCallback(AcceptCallback), null);
    

    Socket listenerSocket = (Socket)ar.AsyncState;
    
  2. 你为什么要读Socket listenerSocket = (Socket)ar.AsyncState; ??

  3. 你在StartListening方法中构造了一个listenerSocket,但是你没有使用它。

错误

当你关闭'listener' (ServerClientSocket),你不应该再调用BeginReceive。就return .

received == 0 socket关闭时,所以不要启动BeginReceive。这就是它永远循环的原因……Begin/End接收直接返回received == 0

public static void ReadCallBack(IAsyncResult ar)
{
    Socket listenerSocket = (Socket)ar.AsyncState;
    int received = 0;
    try
    {
        //Amount of bytes that has been sent
        received = listenerSocket.EndReceive(ar);
    }catch(Exception e)
    {
        received = 0;
    }
    if(received == 0)
    {
        listener.Close();
        return;
    }
    //Create byte array for encoding
    byte[] bytes = new Byte[received];
    Array.Copy(buffer,bytes,received);
    string recievedMessage = Encoding.ASCII.GetString(bytes);
    if (received > 0)
    {
        //do task input
        System.Diagnostics.Debug.WriteLine(recievedMessage);
    }
    //work on this
    listenerSocket.BeginReceive(buffer, 0 , bufferSize, SocketFlags.None, new AsyncCallback(ReadCallBack), listenerSocket);
}

注意

TCP/IP套接字是流套接字,所以你永远不会知道你是否收到了一个完整的数据包或甚至两个。您需要知道您已经收到了完整的消息。通常使用PreLength协议。写一个值,表示后面的数据量

我看到你正在传递0作为Socket的参数。Listen方法,不确定这是否是导致问题的原因但值得尝试将其更改为100

public void Listen(int backlog)

int backlog:等待连接队列的最大长度。

msdn: https://msdn.microsoft.com/nl-nl/library/system.net.sockets.socket.listen (v = vs.110) . aspx