-2

cunstroctor で一定量の TcpListeners を受け入れる「Acceptor」クラスを作成しました。ポート 8484 以上から。

  class Acceptor
{
    private List<TcpListener> Listeners;
    private static int clientCount = 0;
    private static int portStart = 8484;

    public Acceptor(int capacity)
    {
        Listeners = new List<TcpListener>(capacity);
        for (int i = 0; i < capacity; i++)
        {
            Listeners.Add(new TcpListener(IPAddress.Any, portStart));
            portStart++;
        }

        foreach (TcpListener listener in Listeners)
        {
            try
            {
                listener.Start();
                listener.BeginAcceptSocket(new AsyncCallback(EndAccept), null);
            }
            catch (SocketException ex)
            {
                Debug.WriteLine("Failed to start TcpListener, Error {0}.", ex.Message);
            }
        }

        Debug.WriteLine(string.Format("Initiated {0} Listeners from 8484 - {1}.", capacity, portStart));
    }

    public void EndAccept(IAsyncResult IAR)
    {
        TcpListener Listener = (TcpListener)IAR.AsyncState;
        Socket socket = Listener.EndAcceptSocket(IAR);
        frmMain.Clients.Add(clientCount, new Client(socket));
        Listener.Stop();
        Listener = null;
        clientCount++;

        frmMain.Instance.UpdateClients();  
    }
}

しかし、それはうまくいきません。新しい接続を受け入れるとプログラムがクラッシュします。なぜですか?

4

2 に答える 2

0

これは私がリスナーを実装する方法です:

public class EasySocketListener : IDisposable
{
    private Socket _socket;

    public void Start(int port)
    {
        _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _socket.Bind(new IPEndPoint(IPAddress.Any, port));
        _socket.Listen(1);

        StartAccepting();
    }

    private void StartAccepting()
    {
        try
        {
            _socket.BeginAccept((asyncResult) =>
            {
                try
                {
                    Socket clientSocket = _socket.EndAccept(asyncResult);
                    if (OnSocketAccept != null)
                        OnSocketAccept(this, new SocketEventArgs(clientSocket));

                    StartAccepting();
                }
                catch { }
            }, null);
        }
        catch { }
    }

    public void Dispose()
    {
        if (_socket != null)
        {
            _socket.Dispose();
            _socket = null;
        }
    }

    public event EventHandler<SocketEventArgs> OnSocketAccept;
}

これは、複数のクライアント ソケットを受け入れることができます。クライアントが接続すると、OnSocketAccept がトリガーされます。

SocketEventArgs が必要です。

public class SocketEventArgs : EventArgs
{
    public Socket Socket { get; private set; }

    public SocketEventArgs(Socket socket)
    {
        Socket = socket;
    }
}

例:

private void Init()
{
    _listener = new EasySocketListener();
    _listener.OnSocketAccept += Listener_OnSocketAccept;
    _listener.Start(port);
}

private void Listener_OnSocketAccept(object sender, SocketEventArgs e)
{
    Debug.WriteLine( e.Socket.RemoteEndPoint );
}

これは私のブログhttp://csharp.vanlangen.bizに掲載される予定ですが、まだそこには書いていません。ソケットから非同期で読み取るためのメソッドがいくつかあります。

于 2013-09-16T20:12:49.033 に答える