none
Detecting a Disconnected Socket with Powershell RRS feed

  • Question

  • So I've got a powershell script that connect to a socket on a remote device and listens. The remote device will send data at least every 30 seconds. Anyway, I've got an issue where sometimes when the power blinks this device will reboot and disconnect my session. My script never detects this and just sits after this listening to nothing.

    Anyway the script makes the connection with:

    $Socket = New-Object System.Net.Sockets.TcpClient($ip_address, $port)

    Then it listens on this port with:

    $Stream = $Socket.GetStream()
    $Buffer = New-Object System.Byte[] 1024
    $Encoding = New-Object System.Text.AsciiEncoding
    
    while($Socket) {
    	$read = $Stream.Read($Buffer, 0, 1024)
    
    }
    I'm assuming the script gets stuck infinitely in the while loop then at the bottom, always waiting for input but never reading anything. How can I detect the TCP session failing? Thanks!


    Wednesday, November 30, 2016 6:05 PM

Answers

  • Hey Idspispopd (great name),

    You could try setting a receive timout and then use polling to detect for dropped sockets

    $Socket = New-Object System.Net.Sockets.TcpClient($ip_address, $port)
    $socket.ReceiveTimeout = 500
    $Stream = $Socket.GetStream()
    $Buffer = New-Object System.Byte[] 1024
    $Encoding = New-Object System.Text.AsciiEncoding
    
    while($Socket) {
    	$read = $Stream.Read($Buffer, 0, 1024)
        if (!($socket.client.poll([System.Net.Sockets.SelectMode]::SelectRead,1) -and $socket.client.Available -eq 0)){
            $socket.close()
            break;
        }
    }

    I haven't tested it, so I don't know if it works, but I am pretty sure you will occasionally get false disconnects.

    Good Luck!

    Shane


    • Marked as answer by idspispopd Wednesday, December 7, 2016 3:30 PM
    Friday, December 2, 2016 7:57 PM
  • I did some reading and the Read method is blocking, so the script could conceivably hang waiting for data on this line (See this page for more details).

    Sorry, but I've been busy, but I wrote the following code to fix the issue:

    $NoReads = 0
    $Stream = $Socket.GetStream()
    $Buffer = New-Object System.Byte[] 1024
    $Encoding = New-Object System.Text.AsciiEncoding
    
    while($Socket) {
    	if($Stream.DataAvailable) {
    
    		$NoReads = 0
    		$read = $Stream.Read($Buffer, 0, 1024)
    	} else {
    		$NoReads++
    		if($NoReads -gt 30) {
    			$Socket.Close()
    			break
    		}
    
    		sleep 3
    	}
    
    
    }

    I always receive data from this connection every 30 seconds or less, so I should never go 90 seconds. If I do, something is wrong and it should disconnect.

    Thanks for your help. I appreciate it.


    • Marked as answer by idspispopd Wednesday, December 7, 2016 3:30 PM
    • Edited by idspispopd Wednesday, December 7, 2016 3:31 PM Grammar
    Wednesday, December 7, 2016 3:28 PM

All replies

  • Hey Idspispopd (great name),

    You could try setting a receive timout and then use polling to detect for dropped sockets

    $Socket = New-Object System.Net.Sockets.TcpClient($ip_address, $port)
    $socket.ReceiveTimeout = 500
    $Stream = $Socket.GetStream()
    $Buffer = New-Object System.Byte[] 1024
    $Encoding = New-Object System.Text.AsciiEncoding
    
    while($Socket) {
    	$read = $Stream.Read($Buffer, 0, 1024)
        if (!($socket.client.poll([System.Net.Sockets.SelectMode]::SelectRead,1) -and $socket.client.Available -eq 0)){
            $socket.close()
            break;
        }
    }

    I haven't tested it, so I don't know if it works, but I am pretty sure you will occasionally get false disconnects.

    Good Luck!

    Shane


    • Marked as answer by idspispopd Wednesday, December 7, 2016 3:30 PM
    Friday, December 2, 2016 7:57 PM
  • I did some reading and the Read method is blocking, so the script could conceivably hang waiting for data on this line (See this page for more details).

    Sorry, but I've been busy, but I wrote the following code to fix the issue:

    $NoReads = 0
    $Stream = $Socket.GetStream()
    $Buffer = New-Object System.Byte[] 1024
    $Encoding = New-Object System.Text.AsciiEncoding
    
    while($Socket) {
    	if($Stream.DataAvailable) {
    
    		$NoReads = 0
    		$read = $Stream.Read($Buffer, 0, 1024)
    	} else {
    		$NoReads++
    		if($NoReads -gt 30) {
    			$Socket.Close()
    			break
    		}
    
    		sleep 3
    	}
    
    
    }

    I always receive data from this connection every 30 seconds or less, so I should never go 90 seconds. If I do, something is wrong and it should disconnect.

    Thanks for your help. I appreciate it.


    • Marked as answer by idspispopd Wednesday, December 7, 2016 3:30 PM
    • Edited by idspispopd Wednesday, December 7, 2016 3:31 PM Grammar
    Wednesday, December 7, 2016 3:28 PM