BeginAccept 方法后无法关闭套接字
我有一个 C# 程序,在其中创建一个套接字,绑定它,开始监听,然后使用 beginaccept! 但是当我尝试关闭\关闭套接字时,我从 beginaccept AsyncCallback 方法中得到异常!
private void start_listening()
{
main_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iplocal = new IPEndPoint(IPAddress.Any, 11150);
main_socket.Bind(iplocal);
main_socket.Listen(5);
main_socket.BeginAccept(new AsyncCallback(OnClientConnect), null);
}
private void Disconnect_Click(object sender, EventArgs e)
{
main_socket.Shutdown(SocketShutdown.Both);
main_socket.Close();
}
public void OnClientConnect(IAsyncResult asyn)
{
try
{
clients[connected_clients] = new Client("CHANGEME", "127.0.0.1", this);
clients[connected_clients].Socket = main_socket.EndAccept(asyn);
clients[connected_clients].WaitForData();
main_socket.BeginAccept(OnClientConnect, null);
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
非常感谢!
I have a program in c# in which i create a socket, binding it, begin listening and then using beginaccept!
but then when I try to close\shutdown the socket I get exceptions from the beginaccept AsyncCallback method!
private void start_listening()
{
main_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iplocal = new IPEndPoint(IPAddress.Any, 11150);
main_socket.Bind(iplocal);
main_socket.Listen(5);
main_socket.BeginAccept(new AsyncCallback(OnClientConnect), null);
}
private void Disconnect_Click(object sender, EventArgs e)
{
main_socket.Shutdown(SocketShutdown.Both);
main_socket.Close();
}
public void OnClientConnect(IAsyncResult asyn)
{
try
{
clients[connected_clients] = new Client("CHANGEME", "127.0.0.1", this);
clients[connected_clients].Socket = main_socket.EndAccept(asyn);
clients[connected_clients].WaitForData();
main_socket.BeginAccept(OnClientConnect, null);
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}
many thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当 main_socket 关闭时,OnClientConnect() 将被调用,但 main_socket.EndAccept() 应该抛出 ObjectDisposeException。也许您想捕获该异常并将其视为“侦听器套接字已关闭”消息。
您的代码的另一个问题是 main_socket 实际上没有连接到任何东西。在 Disconnect_Click() 中调用 main_socket.Shutdown() 也可能会抛出异常,但这一次应该是 SocketException,表示套接字未连接。我会删除 main_socket.Shutdown() 调用。
When main_socket is closed, OnClientConnect() will be called but main_socket.EndAccept() is supposed to throw an ObjectDisposedException. Perhaps you want to catch that exception and treat it as a "The listener socket has been closed" message.
The other problem with your code is that main_socket is not actually connected to anything. Calling main_socket.Shutdown() in Disconnect_Click() might throw too, but this time it should be a SocketException saying that the socket is not connected. I would remove that main_socket.Shutdown() call.
老话题,但一个解决方案是:保留一个局部变量,以跟踪“关闭/关闭”套接字的时间。我使用
_isShutdown
。当您开始侦听套接字时,设置 _isShutDown = False;
在关闭套接字之前,
set _isShutdown = True;
在
EndAccept(iar)
函数中,仅调用Old topic, but one solution is: Keep a local variable, to keep track of when you "close/shutdown" the socket. I use
_isShutdown
.When you start listening on the socket, set _isShutDown = False;
Before you close the socket,
set _isShutdown = True;
In the
EndAccept(iar)
function, only call“要取消对 BeginAccept 方法的挂起调用,请关闭 Socket。当异步操作正在进行时调用 Close 方法时,将调用提供给 BeginAccept 方法的回调。随后的调用EndAccept 方法将抛出 ObjectDisposeException 来指示操作已被取消。”
Socket.BeginAccept 方法(AsyncCallback,对象)
正确的方法可能是:
1)在服务器端创建客户端socket,连接到监听socket,成功后EndAccept关闭它
2)MSDN建议的方式只是按原样处理此异常
"To cancel a pending call to the BeginAccept method, close the Socket. When the Close method is called while an asynchronous operation is in progress, the callback provided to the BeginAccept method is called. A subsequent call to the EndAccept method will throw an ObjectDisposedException to indicate that the operation has been cancelled."
Socket.BeginAccept Method (AsyncCallback, Object)
proper way could be :
1) create client socket at server, connect to listening socket, after successful EndAccept close it
2) the way suggested by MSDN is just to handle this exception as is
beginaccept 之后是 connEventStatus.WaitOne() 中的线程;状态。您必须通过 connEventStatus.Set() 取消阻止线程; 。这导致该线程将继续。现在您必须通过 YourSocket.Close() 结束套接字。最后,我处理了运行它的线程。但要小心,while 循环不能立即创建新的 beginaccept,您可以通过 connEventStatus.Set() 取消阻塞线程; :-) 。
就这样
After beginaccept is thread in connEventStatus.WaitOne(); state. You must unblock thread by connEventStatus.Set(); . It cause that thread will be continue. Now you must end socket by YourSocket.Close(). For the last I dispose thread in which I run it. But be carefull that while loop can not create new beginaccept imediately you unblock thread by connEventStatus.Set(); :-) .
Thats all