Error 10053 con Netduino (SocketException ErrorCode=10053)


¿ Habéis  obtenido  de forma intermitente  el error 10053  en el proceso de depuración de vuestro código?

#### Exception System.Net.Sockets.SocketException – CLR_E_FAIL (1) ####
#### Message:
#### Microsoft.SPOT.Net.SocketNative::connect [IP: 0000] ####
#### System.Net.Sockets.Socket::Connect [IP: 001d] ####
#### Programa:Connect [IP: 0021] ####
#### Programa:funcion  [IP: 0042] ####
#### Programa::Main [IP: 01b1] ####
#### SocketException ErrorCode = 10053
#### SocketException ErrorCode = 10053

Excepción del tipo ‘System.Net.Sockets.SocketException’ en Microsoft.SPOT.Net.dll
#### SocketException ErrorCode = 10053
#### SocketException ErrorCode = 10053

Este post explora  consejos para solucionar este error molesto: 10053 SocketException ,es decir “Con la conexión establecida fue abortado por el software en el equipo host”

Puede pasar  al azar el error “SocketException 10053”, pero éste  no esta  realmente vinculado a ninguna situación específica, aunque de facto  pueda ocurrir con mayor facilidad cuando el servidor tarde más tiempo para responder a una solicitud (digamos unos 500 ms).

Puede de hecho ocurrir con un sólo 1 agente virtual  en la parte “BeginRead” , pero también puede suceder durante “BeginWrite” también  aunque  el servidor no este  cargado

Para rastrear el problema en la parte servidor podría  usarse   el  WireShark  con objeto de ver  que la solicitud sea enviada al servidor (en este caso  nunca obtuvo respuesta, saliendo SocketException en su lugar),pero  también seria buena  idea instalar  Wireshark   en el servidor remoto  para ver si  la solicitud llega al servidor

En  casos puede  llegar  inmediatamente después de conseguir  un paquete [RST, ACK] ),lo cual puede  significar  que el socket  había sido cerrado del lado del servidor pero es extraña esta excepción  pues no debería ser posible enviar datos en un socket cerrado ,(aunque lo sea a nivel de TCP, pero. NET debería lanza  un error) pues e acuerdo con RFC se deberia  obtener 0 bytes de BeginRead que es mucho más limpio que la obtención de una excepción. Por tanto si el socket se ha cerrado ,la máquina anfitrión  debería detectarlo pues se puede ver que equipo servidor ha enviado [FIN, ACK] antes en el mismo canal TCP.

Así que aquí están, finalmente, la cuestión es  ¿Cómo se puedo detectar que una conexión se ha cerrado en async E / S? (dado que Tuve ningún error al enviar los datos, sólo durante la lectura).
Aquí está el código fuente que obtenía dicho error:
public void StartReading (WebRequest petición) {
if (readBuffer == null)
readBuffer = new byte [ConfigManager.readBufferSize];

try {
request.ParentSocket.networkStream.BeginRead (readBuffer, 0, ConfigManager.readBufferSize, ReadAsyncCallback, petición);
} Catch (IOException ioe) {
Logger.LogError (nombre + “IOException en StartReading: BeginRead” + Request.Path);
ProcessIOException (request, OIE);
} Catch (Exception ex) {
throw new WAException (“StartReading:” + ex.Message, ex);
}
}

AsyncReadHandler public void (IAsyncResult result) {
try {

WebRequest request = (WebRequest) result.AsyncState;

BytesRead int = 0;

try {
BytesRead = request.ParentSocket.networkStream.EndRead (resultado);
} Catch (IOException ioe) {
Logger.LogError (“IOException Si bien la lectura (BytesRead =” + BytesRead + “) la respuesta a” + + Request.Path ioe.Message);
}

/ / Obtener 0 bytes mientras que la lectura mediante conexión se ha cerrado
if (BytesRead == 0) {
Logger.LogWarn (nombre + “> EndRead devuelve 0 bytes, petición =” + Request.Path + “, socket se ha cerrado, el envío de nuevo”);
RecreateSocketAndSend (petición);
volver;
}

} Catch (Exception ex) {
Logger.LogError (nombre + “> AsyncReadHandler: Excepción:” + ex.Message);
throw new WAException (nombre + “> AsyncReadHandler: Exception (“. ex.Message + + “) Path =” + ((WebRequest) result.AsyncState) Path, ex);
}
}

Y aquí la solución: cambiar  el  socket en modo de no bloqueo y tratar de leer 0 bytes. Si se devuelve  0 bytes y SocketError = éxito entonces sé que ha cerrado Socket lado del servidor. Si la conexión está todavía activa entones   SocketError = WouldBlock. Lo interesante es que en ambos casos los resultados son muy rápidos de obtener.

Otras solución podría ser  confiando en los tiempos de espera pero esto es bastante lento, incluso cuando la conexión está todavía. Quizás la solución propuesta  sea  la forma rápida de detectar la desconexión limpia, pues esto no puede funcionar si el paqute “FIN, ACK”  no se recibe por el cliente.

Aquí ID un pedazo de mi código, de ejemplo de como puede solucionarse :

bool previousMode = socket.Blocking;
socket.Client.Blocking = false;
SocketError se;
int BytesRead = socket.Receive (nuevo byte [0], 0, 0, SocketFlags.Peek, a sí mismo);
socket.Blocking = previousMode;

if ((SE == SocketError.Success) && (BytesRead == 0)) {
Logger.LogDebug (“isConnected = false”);
}

Fuente en ingles aqui

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.