.net - serial - probar puerto com1 desde ms dos
¿Cómo puedo verificar si un conector(TCP) está(des) conectado en C#? (4)
¿Cómo debo verificar un socket (TCP) para ver si está conectado?
He leído sobre la propiedad Socket.Connected
en MSDN , pero dice que solo muestra el estado de acuerdo con la última E / S. Esto no es útil para mí, ya que quiero hacer esto antes de intentar leer desde el socket. La sección de observaciones también señala que:
Si necesita determinar el estado actual de la conexión, realice una llamada de envío de cero bytes sin bloqueo. Si la llamada vuelve exitosamente o arroja un código de error WAEWOULDBLOCK (10035), entonces el socket todavía está conectado; de lo contrario, el socket ya no está conectado.
El ejemplo en la misma página muestra cómo hacerlo. (1) Pero una publicación de Ian Griffiths dice que debería leer desde el socket, no enviarlo .
Otro post de Pete Duniho dice:
... después de haber llamado a
Shutdown()
, llame aReceive()
hasta que devuelva0
(suponiendo que el punto extremo remoto no le va a enviar nada en realidad, eso sucederá tan pronto como el extremo remoto haya recibido todos sus datos) ) A menos que haga eso, no tiene ninguna garantía de que el punto extremo remoto haya recibido realmente todos los datos que envió, incluso utilizando un socket persistente.
Realmente no entiendo su afirmación sobre llamar a Receive()
para asegurarme de que el punto extremo remoto ha recibido todos los datos que envié . (¿Los sockets bloquean la recepción hasta que el buffer de envío está vacío?)
Estoy confundido por los diferentes métodos propuestos. ¿Podrías por favor explicarlos?
(1) Me pregunto por qué el MSDN de la propiedad Socket.Connected
asigna una matriz de 1 byte, a pesar de que llama Send
with 0 length?
Realmente no entiendo su afirmación sobre llamar a Receive () para asegurarme de que el punto extremo remoto ha recibido todos los datos que envié.
La publicación de @PeteDuniho no se trata de establecer el estado de la conexión, se trata de terminar la conexión de tal forma que usted sepa cuándo el interlocutor ha recibido todos sus datos.
(¿Los sockets bloquean la recepción hasta que el buffer de envío está vacío?)
No, pero si apaga el socket y luego lee hasta EOS, está esperando que el par lea todos los datos hasta que obtenga EOS y luego cierre el socket. Por lo tanto, tiene la garantía de que todos los datos se han incorporado a la aplicación de pares.
"Si necesita determinar el estado actual de la conexión, realice una llamada de envío de cero byte sin bloqueo. Si la llamada vuelve exitosamente o arroja un código de error WAEWOULDBLOCK (10035), entonces el socket sigue conectado; de lo contrario, el socket es ya no está conectado ". - desafortunadamente, ¡ni siquiera funciona!
mySocket.Blocking = false;
byte[] buffer = new byte[1];
int iSent = mySocket.Send(buffer, 0, SocketFlags.None);
bConnected = mySocket.Connected;
bConnected siempre termina como verdadero, y la llamada siempre regresa con éxito, aunque el cable Ethernet haya sido desenchufado.
Por otra parte, y lamentablemente == el envío de datos reales tampoco detecta la conexión interrumpida.
buffer[0] = 0xff ;
int iSent = mySocket.Send(buffer, 1, SocketFlags.None);
repetidamente devuelve 1, como si realmente hubiera enviado algo. Mientras que el dispositivo en cuestión ni siquiera está conectado más.
La muerte de un socket cambia su comportamiento de varias maneras, por lo que estos métodos son válidos :)
Con ambos métodos, realmente verifica aquellas partes del comportamiento del socket que cambian después de la desconexión.
Realmente no entiendo su afirmación sobre llamar a Receive () para asegurarme de que el punto extremo remoto ha recibido todos los datos que envié. (¿Los sockets bloquean la recepción hasta que el buffer de envío está vacío?)
TCP
es un protocolo confiable, eso significa que cada paquete que envíe debe ser reconocido. El reconocimiento implica enviar los paquetes con el bit ACK
establecido. Estos paquetes pueden contener o no datos adicionales (carga útil).
Cuando el socket está conectado, Receive()
se bloqueará hasta que el socket reciba un paquete con carga útil no vacía. Pero cuando el socket está desconectado, Receive()
regresará tan pronto como llegue el último paquete ACK
.
Llamar a Receive()
garantiza que reciba el último paquete ACK
de su punto extremo remoto o que se produzca un tiempo de espera de desconexión y que no pueda recibir nada más en este socket.
El ejemplo en la misma página muestra cómo hacerlo. (Me pregunto por qué asigna una matriz de 1 byte, a pesar de que llama a Enviar con longitud 0?) Pero una publicación de Ian Griffiths dice que debo leer desde el socket, no enviarlo.
Al send()
ing a un socket, realmente intenta agregar algunos datos al final de la cola de socket. ¿Hay algún lugar en el búfer, luego su Send()
regresa al instante, si no, los bloques de Send()
hasta que haya algún lugar.
Cuando el socket está en estado desconectado, TCP/IP
pila TCP/IP
impide todas las operaciones posteriores con el búfer, es por eso que Send()
devuelve un error.
Send()
implementa una comprobación de puntero básica, esto significa que falla cuando se le pasa un puntero NULL
. Probablemente pase cualquier constante no nula como un puntero, pero es mejor asignar 1 byte en lugar de aumentar la constante, por las dudas.
Puede usar cualquier método que desee, ya que ninguno consume muchos recursos. Siempre que se utilicen para la verificación de la conexión del socket, son idénticos.
En cuanto a mí, preferiría Receive()
, ya que esto es lo que normalmente se ejecuta en un ciclo y esperar. Receive()
un valor distinto de cero de Receive()
, procesas datos; obtienes un cero, procesas la desconexión.
Normalmente, uno usaría el método Socket.Select para determinar el estado de un conjunto de sockets (Socket.Poll para un solo socket).
Ambos métodos le permiten consultar el estado de un socket. Ahora, asumiendo que ha rastreado que el socket se conectó en primer lugar, normalmente llamaría a Select / Poll en el socket antes de intentar una lectura. Si Seleccionar / Encuesta indica que el socket es legible, esto le indica que:
- O el socket tiene los datos disponibles de lectura superior en cuyo caso Receive devolverá los datos disponibles para leer.
- El zócalo se ha cerrado, en cuyo caso cuando llame a Receive 0 bytes se devolverá inmediatamente (es decir, si Select / Poll indica que el zócalo es legible y llama a Receive pero lo devuelve inmediatamente con 0 bytes, entonces sabrá que la conexión ya sea cerrado, reiniciado o terminado.
Personalmente, nunca he usado Poll. Siempre he usado Select pero MSDN parece sugerir que Poll es prácticamente lo mismo que Select pero para sockets únicos.
También agregaré que, en la mayoría de los casos, usar Select es la manera más eficiente y mejor de manejar las conexiones Socket.