socket servidor receive mensaje mandar cliente async c# sockets

c# - servidor - Excepción WSACancelBlockingCall



sockets c# windows forms (5)

¡Igual que aquí! ¡Pero me di cuenta de que el ReceiveBuffer en el lado del servidor estaba inundado por los clientes! (En mi caso, un montón de escáneres RFID, que siguieron enviando spam al TagCode, en lugar de dejar de enviar hasta que llegue el próximo TagCode)

Ayudó a elevar los ReceiveBuffers y reconfigurar los escáneres ...

Ok, tengo una extraña excepción lanzada desde mi código que me ha estado molestando por años.

System.Net.Sockets.SocketException: A blocking operation was interrupted by a call to WSACancelBlockingCall at System.Net.Sockets.Socket.Accept() at System.Net.Sockets.TcpListener.AcceptTcpClient()

MSDN no es muy útil en esto: http://msdn.microsoft.com/en-us/library/ms741547(VS.85).aspx y ni siquiera sé cómo comenzar a solucionar este problema. Solo se lanza 4 o 5 veces al día, y nunca en nuestro entorno de prueba. Solo en sitios de producción y en TODOS los sitios de producción.

He encontrado muchas publicaciones que me preguntan sobre esta excepción, pero no hay respuestas definitivas sobre qué la está causando y cómo manejarla o prevenirla.

El código se ejecuta en un hilo de fondo separado, el método comienza:

public virtual void Startup() { TcpListener serverSocket= new TcpListener(new IPEndPoint(bindAddress, port)); serverSocket.Start();

luego ejecuto un ciclo colocando todas las conexiones nuevas como trabajos en un grupo de subprocesos por separado. Se vuelve más complicado debido a la arquitectura de la aplicación, pero básicamente:

while (( socket = serverSocket.AcceptTcpClient()) !=null) //Funny exception here { connectionHandler = new ConnectionHandler(socket, mappingStrategy); pool.AddJob(connectionHandler); } }

A partir de ahí, el pool tiene sus propios hilos que se encargan de cada trabajo en su propio hilo, por separado.

Tengo entendido que AcceptTcpClient () es una llamada de bloqueo, y que de alguna manera winsock le dice al hilo que deje de bloquear y continúe la ejecución ... ¿pero por qué? ¿Y qué se supone que debo hacer? ¿Atrapar la excepción e ignorarla?

Bueno, creo que algún otro hilo está cerrando el socket, pero ciertamente no es de mi código. Lo que me gustaría saber es si este socket está cerrado por el cliente de conexión (en el otro lado del socket) o está cerrado por mi servidor. Porque como es en este momento, cada vez que ocurre esta excepción, apaga mi puerto de escucha, cerrando efectivamente mi servicio. Si esto se hace desde una ubicación remota, entonces es un problema importante.

Alternativamente, ¿podría ser simplemente el servidor IIS que cierra mi aplicación y cancela todos mis hilos de fondo y métodos de bloqueo?


¿Es posible que serverSocket se cierre desde otro hilo? Eso causará esta excepción.


Esta es mi solución de ejemplo para evitar WSAcancelblablabla: defina su hilo como global, entonces puede usar el método de invocación así:

private void closinginvoker(string dummy) { if (InvokeRequired) { this.Invoke(new Action<string>(closinginvoker), new object[] { dummy }); return; } t_listen.Abort(); client_flag = true; c_idle.Close(); listener1.Stop(); }

Después de invocarlo, cierre primero el hilo y luego el indicador de bucle para siempre para bloquear la espera adicional (si la tiene), luego cierre tcpclient y luego detenga al oyente.


Esto podría suceder en serverSocket.Stop() . Lo llamé cuando se llamó a Dispose .

Así es como se veía mi manejo de excepciones para el hilo de escucha:

try { //... } catch (SocketException socketEx) { if (_disposed) ar.SetAsCompleted(null, false); //exception because listener stopped (disposed), ignore exception else ar.SetAsCompleted(socketEx, false); }

Ahora lo que sucedió fue que, de vez en cuando, la excepción ocurría antes de que _disposed se estableciera en verdadero. Entonces la solución para mí fue hacer que todo fuera seguro.


Más recientemente, vi esta excepción al usar HttpWebRequest para PONER un archivo grande y se pasó el tiempo de espera.

Usando el siguiente código, siempre y cuando el tiempo de carga sea> 3 segundos, causará este error tanto como yo pueda ver.

string path = "Reasonably large file.dat"; int bufferSize = 1024; byte[] buffer = new byte[bufferSize]; System.Net.HttpWebRequest req = (HttpWebRequest)System.Net.HttpWebRequest.Create("Some URL"); req.Method = "PUT"; req.Timeout = 3000; //3 seconds, small timeout to demonstrate long length = new System.IO.FileInfo(path).Length; using (FileStream input = File.OpenRead(path)) { using (Stream output = req.GetRequestStream()) { long remaining = length; int bytesRead = 0; while ((bytesRead = input.Read(buffer, 0, (int)Math.Min(remaining, (decimal)bufferSize))) > 0) { output.Write(buffer, 0, bytesRead); remaining -= bytesRead; } output.Close(); } input.Close(); }