多个 Tcp 侦听器不工作
本文关键字:工作 侦听器 Tcp 多个 | 更新日期: 2023-09-27 18:31:34
我做了一个"Acceptor"类,在cunstroctator中它接受一定数量的TcpListeners。从端口 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();
}
}
但是,这行不通。接受新连接时程序崩溃,为什么会这样?
您将 null 作为 BeginAcceptSocket 中的"状态"传递,因此当您尝试将其转换回去然后使用它时会出现错误。
尝试更改此行:
listener.BeginAcceptSocket(new AsyncCallback(EndAccept), null);
自:
listener.BeginAcceptSocket(new AsyncCallback(EndAccept), listener);
这是我实现侦听器的方式:
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 会触发。
需要套接字事件参数:
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,但还没有写在那里。您可以找到一些从套接字读取异步的方法。