Timeoutexception on TCP not handled - vb.net

I took this code from a website since VS 2010 doesn't support the timeout for the TCP connections:
Private Function ConnectWithTimeout() As Boolean
Dim ar As IAsyncResult = TCPClient.BeginConnect(IPAddress, TCPPort, Nothing, Nothing)
Dim wh As System.Threading.WaitHandle = ar.AsyncWaitHandle
Try
If Not ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2), False) Then
TCPClient.Close()
TCPClient = New System.Net.Sockets.TcpClient
Throw New TimeoutException()
End If
Catch ex As Exception
ThrowError("Timeout on connecting to " & IPAddress & " at port " & TCPPort & ".")
Return False
Finally
wh.Close()
End Try
Return True
End Function
And it works fine, but everytime, it gives me this on the debug output:
"A first chance exception of type 'System.TimeoutException' occurred in"
Even if I'm catching all the exceptions. Is there a way to get rid of this exception message as it is handled?
I've tried this:
Dim connectDone As New System.Threading.AutoResetEvent(False)
TCPClient.BeginConnect(IPAddress, TCPPort, New AsyncCallback(Sub(ar As IAsyncResult)
TCPClient.EndConnect(ar)
connectDone.Set()
End Sub), TCPClient)
'client.BeginConnect("127.0.0.1", 80, new AsyncCallback(delegate( IAsyncResult ar ) { client.EndConnect( ar ); connectDone.Set(); }), client);
If Not connectDone.WaitOne(2000) Then
Debug.WriteLine("TIMEOUT")
Return False
End If
Return True
But it gives me InvalidOperationException on the beginconnect line:
BeginConnect cannot be called while another asynchronous operation is in progress on the same Socket.

Private Function ConnectWithTimeout() As Boolean
Dim ar As IAsyncResult
Dim wh As System.Threading.WaitHandle
Try
ar = TCPClient.BeginConnect(IPAddress, TCPPort, Nothing, Nothing)
wh = ar.AsyncWaitHandle
Cath ex as Exception
'Code to catch exception
End Try
Try
If Not ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2), False) Then
TCPClient.Close()
TCPClient = New System.Net.Sockets.TcpClient
Throw New TimeoutException()
End If
Catch ex As Exception
ThrowError("Timeout on connecting to " & IPAddress & " at port " & TCPPort & ".")
Return False
Finally
wh.Close()
End Try
Return True
End Function

Related

Vb.net application connect to multiple server via TCP/IP

I made a Winforms application to work with 4 different machines by connecting with them via TCP/IP. Somehow, the connection sometimes seems disconnected and reconnecting after a short while. May I know is it I used too much TCP client and caused them congested??
Below is the function/method to connect those machine...with 4 of them different function names to connect each of the machine, but the code is more or less the same:
Public Async Sub connect_Machine_Ethernet(ByVal mainForm As Form1)
If Machine_COMPort.IsOpen Then
Machine_COMPort.Close()
End If
If (IsNothing(Machine_client)) Then
'do nothing, since obj is not created
Else
Try
Machine_client.GetStream.Close()
Machine_client.Close()
Catch exp As Exception
End Try
End If
Try
Machine_client = New TcpClient
Machine_client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, True)
Dim result = Machine_client.BeginConnect(Machine_ModuleIP_txt.Text, CInt(Machine_ModulePort_txt.Text), Nothing, Nothing)
result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1))
Machine_client.GetStream.BeginRead(Machine_ethernet_buffer, 0, Machine_ethernet_buffer.Length, AddressOf Machine_TCP_read, Machine_ethernet_buffer)
DisplayMsg("Machine Ethernet connection established")
manual_connection_LED.StateIndex = 3
Machine_client_isConnected = True
Machine_TCP_Reconnect_btn.Invoke(Sub() Machine_TCP_Reconnect_btn.Visible = False)
Catch ex As Exception
DisplayMsg("Error : Unable to connect to the Machine Ethernet connection")
manual_connection_LED.StateIndex = 0
Machine_client_isConnected = False
If (IsNothing(Machine_client)) Then
'do nothing, since obj is not created
Else
Try
Machine_client.GetStream.Close()
Machine_client.Close()
Catch exp As Exception
End Try
End If
End Try
End Sub
'Read Machine TCP message
Sub Machine_TCP_read(ByVal ar As IAsyncResult)
Try
Dim buffer() As Byte = ar.AsyncState
Dim bytesRead As Integer = Machine_client.GetStream.EndRead(ar)
Dim Message As String = System.Text.Encoding.ASCII.GetString(Machine_ethernet_buffer, 0, bytesRead)
If Message = "" Then
'----check connection
If Machine_client.Connected Then
Machine_client.Close()
connect_Machine_Ethernet(Me)
End If
Else
DisplayMsg("Input Received from machine : " & Message)
Process_machine_Feedback(Message) 'perform any data logic from the message
Machine_client.GetStream.BeginRead(Machine_ethernet_buffer, 0, Machine_ethernet_buffer.Length, AddressOf Machine_TCP_read, Machine_ethernet_buffer)
End If
Catch ex As Exception
DisplaySystemMsg(ex.Message)
DisplayMsg("Marking machine Ethernet disconnected from the server")
manual_connection_LED.StateIndex = 0
Machine_client_isConnected = False
Exit Sub
End Try
End Sub
'Send message to TCP
Public Sub Machine_TCP_send(ByVal str As String)
Try
sWriter = New StreamWriter(Machine_client.GetStream)
sWriter.WriteLine(Chr(2) & str & Chr(3)) 'add prefix suffix
sWriter.Flush()
DisplayMsg("Message send to the machine via TCP: " & str)
Catch ex As Exception
DisplayMsg("Error : Message failed to send to themachine!")
End Try
End Sub

SSIS Script Task supress onerror

I have a script task which downloads a file using a HTTP connection object. This script task is part of a package which is called by another package. Sometimes the connection cannot be established. In these instances I want to retry the connection a number of times before finally raising an error if the connection attempts fail.
I tried to implement this. It appeared to work and the task does not fail. However an OnError event is still propagated every time an exception happens in the script task even though the script task doesn't fail. The fail occurs once control is passed from the child package back to the parent package.
Public Sub Main()
Dim tryTimes As Integer = 0
Dim maxTimes As Integer = 4
While (True)
Try
Dim nativeObject As Object = Dts.Connections("HTTP Connection Manager").AcquireConnection(Nothing)
'Create a new HTTP client connection
Dim connection As New HttpClientConnection(nativeObject)
Dim filename As String = Dts.Variables("Working_File").Value
connection.DownloadFile(filename, True)
Dts.TaskResult = ScriptResults.Success
Exit While
Catch ex As Exception
If (tryTimes < maxTimes) Then
tryTimes = tryTimes + 1
Thread.Sleep(30000)
Else
MsgBox(ex.Message)
Dts.TaskResult = ScriptResults.Failure
Throw
End If
End Try
End While
End Sub
I am hoping to get a solution where the OnError event is not called unless the connection attempts fails a certain number of times.
Try writing the same code an Fire a Warning on first 4 trial and on the 5th trial fire an error, i am not sure if it will works:
Public Sub Main()
Dim tryTimes As Integer = 0
Dim maxTimes As Integer = 4
While (True)
Try
Dim nativeObject As Object = Dts.Connections("HTTP Connection Manager").AcquireConnection(Nothing)
'Create a new HTTP client connection
Dim connection As New HttpClientConnection(nativeObject)
Dim filename As String = Dts.Variables("Working_File").Value
connection.DownloadFile(filename, True)
Dts.TaskResult = ScriptResults.Success
Exit While
Catch ex As Exception
If (tryTimes < maxTimes) Then
tryTimes = tryTimes + 1
Dts.Events.FireWarning(0, "Error ignored", _
"Retrying in 30 seconds", String.Empty, 0)
Thread.Sleep(30000)
Else
Dts.Events.FireError(-1, "", "Error message: " & ex2.ToString(), "", 0)
Dts.TaskResult = ScriptResults.Failure
End If
End Try
End While
End Sub
Reference
How to suppress OnError event for a specific error in a Script task (SSIS 2005)
You'll want to use a label, outside the try, and a GoTo within your catch
Public Sub Main()
Dim tryTimes As Integer = 0
Dim maxTimes As Integer = 4
RunCode: 'Label here
While (True)
Try
'your code here
Exit While
Catch ex As Exception
If (tryTimes < maxTimes) Then
tryTimes = tryTimes + 1
Thread.Sleep(30000)
GoTo RunCode 'after we catch the exception and eval tryTimes go back and retry
Else
'MsgBox(ex.Message)
Dts.Events.FireError(-1, "", "Error message: " & ex.ToString(), "", 0)
Dts.TaskResult = ScriptResults.Failure
'Throw
End If
End Try
End While
End Sub

"Response received is incomplete"

So I reversed the syntax of this send sms code from c# to vb net so I can reuse it.
The code works sometimes, but for some reason it would often give me the "response received is incomplete" exception.
I was thinking perhaps my code is processing commands faster than my GSM device, could handle, so I tried increasing the timeout response for the serial port, still ends up with this exception.
What do you think is the problem and what would you recommend I do to solve it?
Public Class SmsHelper
Public receiveNow As AutoResetEvent
#Region "Open and Close Ports"
'Open Port
Public Function OpenPort(portName As String, baudRate As Integer, dataBits As Integer, readTimeout As Integer, writeTimeout As Integer) As SerialPort
receiveNow = New AutoResetEvent(False)
Dim port As New SerialPort()
Try
port.PortName = portName
'COM1
port.BaudRate = baudRate
'9600
port.DataBits = dataBits
'8
port.StopBits = StopBits.One
'1
port.Parity = Parity.None
'None
port.ReadTimeout = readTimeout
'300
port.WriteTimeout = writeTimeout
'300
port.Encoding = Encoding.GetEncoding("iso-8859-1")
port.NewLine = vbCrLf
AddHandler port.DataReceived, AddressOf port_DataReceived
port.Open()
port.DtrEnable = True
port.RtsEnable = True
Catch ex As Exception
Throw ex
End Try
Return port
End Function
' Send AT Command
Public Function SendATCommand(port As SerialPort, command As String, responseTimeout As Integer, errorMessage As String) As String
Try
port.DiscardOutBuffer()
port.DiscardInBuffer()
receiveNow.Reset()
port.Write(command & Convert.ToString(vbCrLf))
Dim input As String = ReadResponse(port, responseTimeout)
Console.WriteLine("Received data is " & input)
If (input.Length = 0) OrElse ((Not input.EndsWith(vbCr & vbLf & "> ")) AndAlso (Not input.EndsWith(vbCr & vbLf & "OK" & vbCr & vbLf))) Then
Throw New ApplicationException("No success message was received.")
End If
Return input
Catch ex As Exception
Throw ex
Finally
End Try
End Function
'Receive data from port
Public Sub port_DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
Try
If e.EventType = SerialData.Chars Then
receiveNow.[Set]()
End If
Catch ex As Exception
Throw ex
End Try
End Sub
Public Function ReadResponse(port As SerialPort, timeout As Integer) As String
Dim serialPortData As String = ""
Try
Do
If receiveNow.WaitOne(timeout, False) Then
Dim data As String = port.ReadLine()
serialPortData += data
Else
'Console.WriteLine("SerialPortData data is " & serialPortData)
If serialPortData.Length > 0 Then
Console.WriteLine("SerialPortData is " & serialPortData.ToString)
Throw New ApplicationException("Response received is incomplete.")
Else
Throw New ApplicationException("No data received from phone.")
End If
End If
Loop While Not serialPortData.EndsWith(vbCr & vbLf & "OK" & vbCr & vbLf) AndAlso Not serialPortData.EndsWith(vbCr & vbLf & "> ") AndAlso Not serialPortData.EndsWith(vbCr & vbLf & "ERROR" & vbCr & vbLf)
Catch ex As Exception
Throw ex
End Try
Return serialPortData
End Function
Shared readNow As New AutoResetEvent(False)
Public Function SendMessage(port As SerialPort, phoneNo As String, message As String) As Boolean
Dim isSend As Boolean = False
Try
Dim recievedData As String = SendATCommand(port, "AT", 3000, "No phone connected")
Dim command As String = "AT+CMGF=1" + Char.ConvertFromUtf32(13)
recievedData = SendATCommand(port, command, 3000, "Failed to set message format.")
' AT Command Syntax - http://www.smssolutions.net/tutorials/gsm/sendsmsat/
command = (Convert.ToString("AT+CMGS=""") & phoneNo) + """" + Char.ConvertFromUtf32(13)
recievedData = SendATCommand(port, command, 3000, "Failed to accept phoneNo")
'wait(2)
command = message & Char.ConvertFromUtf32(26)
recievedData = SendATCommand(port, command, 3000, "Failed to send message")
Console.WriteLine("Received data is " & recievedData)
If recievedData.EndsWith(vbCr & vbLf & "OK" & vbCr & vbLf) Then
isSend = True
ElseIf recievedData.Contains("ERROR") Then
isSend = False
End If
Return isSend
Catch ex As Exception
Throw ex
End Try
End Function
Private Shared Sub DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
Try
If e.EventType = SerialData.Chars Then
readNow.[Set]()
End If
Catch ex As Exception
Throw ex
End Try
End Sub
#End Region
End Class

How do I connect VB.Net Winforms App to ServiceM8

It appears that I am able to get the temp-token, but when I try to convert to a permanent token I get "BAD REQUEST". Any help would be appreciated.
Code is hooked to WebBrowser1.Navigated
Dim strTempToken As String = ""
If WebBrowser1.Url.ToString.ToUpper.StartsWith("HTTPS://GO.SERVICEM8.COM/DASHBOARD?&S_AUTH=") Then
Try
Dim arrURL As Array = Split(WebBrowser1.Url.ToString, "&")
strTempToken = arrURL(1).ToString.Replace("s_auth=", "")
Catch ex As Exception
MessageBox.Show("Fail-1." & ex.Message)
End Try
If strTempToken.Length > 0 Then
Try
Dim hc As New System.Net.Http.HttpClient
Dim req As New System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, "https://www.servicem8.com/oauth/access_token")
req.Headers.Add("client_id", strClientID)
req.Headers.Add("client_secret", strClientSecret)
req.Headers.Add("code", strTempToken) '
Dim res As System.Net.Http.HttpResponseMessage = Await hc.SendAsync(req)
My.Computer.FileSystem.WriteAllText(strKeyPath & "servicem8-perm-key.txt", res.RequestMessage.RequestUri.ToString, False)
MessageBox.Show("Success")
WebBrowser1.Url = New Uri("")
Catch ex As Exception
MessageBox.Show("Fail-2." & ex.Message)
End Try
End If
End If

VB.net - see if remote file exists

I have a function to check if a remote file exists after being passed the URL. Assuming it doesn't exist the function would return 0 to be used in another sub. Here's what I have:
Public Function RemoteFileExists(ByVal fileurl As String) As Integer
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(fileurl), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.GetFileSize
Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
If response.StatusCode = FtpStatusCode.ActionNotTakenFileUnavailable Then
RemoteFileExists = 0
Exit Function
End If
Dim fileSize As Long = response.ContentLength
MsgBox(fileSize)
If fileSize > 0 Then
RemoteFileExists = 1
Else
RemoteFileExists = 0
End If
End Function
When I run the app and purposely supply a URL that doesn't exist Visual Studio gives me System.Net.WebException was unhandled. Message=The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
I assumed that the "if response.StatusCode..." would handle that rather than shutting down the program.
Any help appreciated.
DWM
First of all you should switch from Integer to Boolean since you only return either 1 or 0 anyway. A Boolean can be either True or False.
Secondly, you should wrap everything in a Try/Catch block to handle any error that might occur. Wrapping code in Try/Catch can catch most errors (except for the most extreme ones) and putting it around code that could throw an error saves you from having your application crash for the more simple errors.
And finally, you should use Return <value> instead of RemoteFileExists = <value>, since Return will both return the wanted value AND exit the function.
Example implementation:
Public Function RemoteFileExists(ByVal fileurl As String) As Boolean
Try
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(fileurl), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.GetFileSize
Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
If response.StatusCode = FtpStatusCode.ActionNotTakenFileUnavailable Then
Return False 'Return instead of Exit Function
End If
Dim fileSize As Long = response.ContentLength
MsgBox(fileSize)
If fileSize > 0 Then
Return True
Else
Return False
End If
Catch ex As Exception 'Catch all errors
'Log the error if you'd like, you can find the error message and location in "ex.Message" and "ex.StackTrace".
MessageBox.Show("An error occurred:" & Environment.NewLine & ex.Message & Environment.NewLine & ex.StackTrace, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return False 'Return False since the checking failed.
End Try
End Function
In the Catch block, ex.Message is the error message, and ex.StackTrace is where in the code the error occurred.