问题
I'm trying to implement async sockets for my project. Here's the code
public void Start(int listeningPort)
{
var ipHostInfo = Dns.Resolve(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList[0];
var localEndPoint = new IPEndPoint(ipAddress, listeningPort);
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_listener.Bind(localEndPoint);
_listener.Listen(3000);
Started = true;
Task.Factory.StartNew(() =>
{
while (Started)
{
allDone.Reset();
_listener.BeginAccept(AcceptCallback, _listener);
allDone.WaitOne();
}
});
}
public void Stop()
{
Started = false;
_listener.Shutdown(SocketShutdown.Both); //<-- throws SocketException
_listener.Close(2000);
_listener = null;
}
public void Kick(IClient client)
{
try
{
Clients.Remove(client);
client.Socket.Shutdown(SocketShutdown.Both);
client.Socket.Close();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
private void AcceptCallback(IAsyncResult ar)
{
Socket handler = null;
try
{
allDone.Set();
var listener = (Socket) ar.AsyncState;
handler = listener.EndAccept(ar);
var client = new Client(this, handler);
Clients.Add(client);
var state = new StateObject();
state.Socket = handler;
handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
var client = ClientBySocket(handler);
if(handler != null && client != null) Kick(client);
}
}
private void ReadCallback(IAsyncResult ar)
{
Socket handler = null;
try
{
var state = (StateObject) ar.AsyncState;
handler = state.Socket;
var bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
if (Received != null)
{
var buff = new byte[bytesRead];
if (buff[0] == 0)
{
Stop();
}
return;
Array.Copy(state.Buffer, buff, bytesRead);
Debug.WriteLine(Encoding.UTF8.GetString(buff));
try
{
Received(this, new ReceiveArgs(buff));
}
catch(Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
var client = ClientBySocket(handler);
if (handler != null && client != null) Kick(client);
}
}
but everytime I call Stop (which in turn, calls shutdown) (no matter clients are connected or not), Socket.Shutdown throws SocketException with message
Additional information: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
I'm really stuck here. Anyone knows what I'm doing wrong?
回答1:
Your listening socket is not connected. I think the message says this quite well. Everytime you accept a connection you get a new socket that is independent. The original socket is never connected to anything.
Just don't call Shutdown on it.
Btw, your Accept loop is using async IO, then waiting for it to complete. That makes no sense. Use the synchronous version.
来源:https://stackoverflow.com/questions/23963359/socket-shutdown-throws-socketexception