如何重新连接TCPClient套接字连接

时间:2016-04-12 14:24:44

标签: vb.net exception-handling tcpclient

我真的把头发拉过这一头。 我使用异步tcp连接连接到服务器。只要远程服务器运行,应用程序就可以正常运行。如果我第一次运行应用程序并且服务器没有运行,那么应用程序将继续尝试使用计时器(代码中的timer1)每10秒连接一次,并且只要服务器联机就会连接正常。 服务器意外断开连接时出现问题。我可以在子ReceiveCallback()中捕获异常,但它不会重新连接,即使服务器重新联机。我使用子DroppedConnection()重新启动连接过程,但在异常后,计时器似乎没有运行,我得到错误。这是我的代码(一些不相关的东西已被删除)

Private Sub MainForm_OnLoad(sender As Object, e As EventArgs) Handles MyBase.Load
    PopulateInstalledPrintersCombo()
    Timer1.Enabled = False
    If (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed) Then
        With System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion
            VNLabel.Text = "V" & .Major & "." & .Minor & "." & .Build
        End With
    End If
    ' VNLabel.Text = "Release: " & System.Windows.Forms.Application.ProductVersion.ToString





    ServerAddress.Text = My.Settings.savedIP
    PortNumber.Text = My.Settings.savedPort
    TerminalId.Text = My.Settings.savedTerminalID
    PrinterDr.Text = My.Settings.savedPrinter
    ConnectBtn.Visible = False
End Sub



Private Sub ConnectBtn_Click(sender As Object, e As EventArgs) Handles ConnectBtn.Click

    If ServerAddress.Text = "" OrElse PortNumber.Text = "" OrElse TerminalId.Text = "" OrElse PrinterDr.Text = "" Then

        MessageBox.Show("Please ensure all connection fields are filled before continuing.")

    Else
        ipAd = ServerAddress.Text
        MakeConnection(ipAd, False)
    End If
End Sub


Private Sub MakeConnection(serverAddressString, conStat)
    'This is where we make the connection
    prtNum = My.Settings.savedPort
    TermID = My.Settings.savedTerminalID
    serverAddressString = My.Settings.savedIP
    If serverAddressString = "" Then
        ipAd = ServerAddress.Text
        serverAddressString = ipAd
        My.Settings.savedIP = ipAd
    Else
        ipAd = serverAddressString
    End If
    Console.WriteLine("ipaddress is: " & ipAd)
    WriteLog("In MakeConnection() IP address is : " & ipAd)

    Dim ipAddress As IPAddress = IPAddress.Parse(ipAd)
    Dim remoteEP As New IPEndPoint(ipAddress, prtNum)
    isRunning = conStat

    Try
        If isRunning = False Then
            client = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            ' Connect to the remote endpoint.
            client.BeginConnect(remoteEP, New AsyncCallback(AddressOf AsynchronousClient.ConnectCallback), client)
            UpdateList("Connecting..." & Date.Today.ToString & " " & TimeOfDay)
            ConnectBtn.Text = "Connecting..."
            WriteLog("Connecting..." & Date.Today.ToString & " " & TimeOfDay)

            ' Wait for connect.

            If (AsynchronousClient.connectDone.WaitOne(5000, True)) Then
                If client.Connected = True Then
                    conStat = True
                    UpdateList("Begin ----")
                    Console.WriteLine("Connected to host")
                    ' Send test data to the remote Robot.
                    AsynchronousClient.Send(client, Chr(2) & "(login (term-id " & TermID & "))" & Chr(3))
                    AsynchronousClient.sendDone.WaitOne(5000)
                    UpdateList("Send-------" & Chr(2) & "(login (term-id " & TermID & "))" & Chr(3))
                    WriteLog("Send-------" & Chr(2) & "(login (term-id " & TermID & "))" & Chr(3))
                    isRunning = True
                    ConnectBtn.Text = "Connected"
                    isReceived = False
                    UpdateList("Waiting for Response Data...")
                    trd = New Thread(AddressOf ReceiveThread)
                    trd.IsBackground = True
                    trd.Start()
                Else
                    UpdateList("Not Connected ----")
                    Console.WriteLine("Host not available")
                    isRunning = False
                    UpdateList("Host not available. Connecting..." & Date.Today.ToString & " " & TimeOfDay)
                    'timer not starting here for some reason??

                    Console.WriteLine("waiting for plant manager...")
                    'client.Shutdown(SocketShutdown.Both)
                    client.Close()

                    DroppedConnection(0)

                End If
            Else
                Console.WriteLine("Host not available")
                isRunning = False
                UpdateList("Host not available. Connecting..." & Date.Today.ToString & " " & TimeOfDay)
                DroppedConnection(0)
            End If
        End If
    Catch ex As Exception
        WriteLog("ReConnection Error :" & Date.Today.ToString & " " & TimeOfDay & " " & ex.Message)
    End Try
End Sub

Private Sub ReceiveThread()

    AsynchronousClient.Receive(client)

    Do

        Thread.Sleep(100)

        If MainForm.isReceived = False Then
            If main_Response.Length > 1 Then
                If main_Response.Contains("req-end") Then
                    UpdateList(main_Response)
                    WriteLog(main_Response)
                    main_Response = String.Empty
                Else

                End If


            End If
            Thread.Sleep(500)
        End If
    Loop
End Sub

Private Sub DroppedConnection(ReConn)
    'WriteLog("Dropped Connection : Trying Reconnect...")
    Console.Write("Dropped Connection()")


    If ReConn = 1 Then

        MakeConnection(My.Settings.savedIP, False)
    Else
        isRunning = False
        Second = 0
        'client.Close()
        'client.Dispose()
        Timer1.Interval = 1000
        Timer1.Enabled = True

        Timer1.Start() 'Timer starts functioning


    End If


End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

    Second = Second + 1
    Console.WriteLine(Second)
    If Second >= 10 Then
        Timer1.Stop() 'Timer stops functioning
        Timer1.Enabled = False
        MakeConnection(ServerAddressString, False)
    End If

End Sub

Public Class StateObject
    ' Client socket.
    Public workSocket As Socket = Nothing
    ' Size of receive buffer.
    Public Const BufferSize As Integer = 65535
    ' Receive buffer.
    Public buffer(BufferSize) As Byte
    ' Received data string.
    Public sb As New StringBuilder
End Class 'StateObject


Public Class AsynchronousClient
    ' The port number for the remote device.
    Const port As Integer = 3001

    ' ManualResetEvent instances signal completion.
    Public Shared connectDone As New ManualResetEvent(False)
    Public Shared sendDone As New ManualResetEvent(False)
    Public Shared receiveDone As New ManualResetEvent(False)

    ' The response from the remote device.
    Public Shared response As String = String.Empty




    Public Shared Sub ConnectCallback(ByVal ar As IAsyncResult)
        ' Retrieve the socket from the state object.
        Dim client As Socket = CType(ar.AsyncState, Socket)

        Try
            If client.Connected = True Then
                client.EndConnect(ar)


                Console.WriteLine("ConnectCallback() Socket connected to {0}", client.RemoteEndPoint.ToString())
                MainForm.WriteLog("ConnectCallback() Connected to :" & client.RemoteEndPoint.ToString())
                MainForm.ServerResponses.Items.Add("connected..." & client.RemoteEndPoint.ToString())
                MainForm.ConnectBtn.Text = "Connected"
                ' Signal that the connection has been made.
                connectDone.Set()
                MainForm.WriteLog("ConnectCallBack() :Socket connected" & client.RemoteEndPoint.ToString() & Date.Today.ToString & " " & TimeOfDay)

            End If
        Catch e As Exception
            MainForm.ConnectBtn.Text = "Connect"
                MainForm.WriteLog("ConnectCallback () Connection Error :" & Date.Today.ToString & " " & TimeOfDay & " " & e.Message)
            MainForm.DroppedConnection(0)
            'Environment.Exit(0)
        End Try

    End Sub 'ConnectCallback


    Public Shared Sub Receive(ByVal client As Socket)

        ' Create the state object.
        Dim state As New StateObject
        Try
            If client.Connected = True Then


                state.workSocket = client

                ' Begin receiving the data from the remote device.
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
            Else

                MainForm.DroppedConnection(0)
            End If

        Catch ex As Exception

            MainForm.WriteLog("Async Class Recieve() Error :" & Date.Today.ToString & " " & TimeOfDay & " " & ex.Message)
            MainForm.DroppedConnection(0)
        End Try

    End Sub 'Receive


    Public Shared Sub ReceiveCallback(ByVal ar As IAsyncResult)

        Dim state As StateObject = CType(ar.AsyncState, StateObject)
            Dim client As Socket = state.workSocket
            Dim strReceiveBuffer As String = String.Empty

            ' Read data from the remote device.
            Dim bytesRead As Integer


        'While client.Connected
        If (AsynchronousClient.connectDone.WaitOne(5000, True)) Then
            Try

                If client.Connected = True Then
                    bytesRead = client.EndReceive(ar)
                    Console.WriteLine("Socket Connected")
                    If bytesRead > 0 Then
                        state.sb.Clear()
                        ' There might be more data, so store the data received so far.
                        state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead))

                        strReceiveBuffer = state.sb.ToString()
                        MainForm.main_Response = state.sb.ToString()

                        If strReceiveBuffer.IndexOf("doses-remaining") > 0 Then
                            response = state.sb.ToString()
                            MainForm.GetLabelTextToString(response)
                            'receiveDone.Set()
                            'isReceived = True
                            'Return
                        End If

                        ' Get the rest of the data.
                        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)


                    Else
                        ' All the data has arrived; put it in response.
                        If state.sb.Length > 1 Then

                            response = state.sb.ToString()

                        End If
                        ' Signal that all bytes have been received.
                        receiveDone.Set()
                        isReceived = True
                    End If
                Else
                    MainForm.WriteLog("RecieveCallback() Error outside catch :" & Date.Today.ToString & " " & TimeOfDay)
                    MainForm.UpdateList("RecievecallBack error, attempting reconnect..." & client.RemoteEndPoint.ToString())

                    MainForm.isRunning = False
                    MainForm.DroppedConnection(0)
                End If


            Catch ex As Exception

                'MessageBox.Show("ReceiveCallback Error, Check Log.")

                MainForm.WriteLog("RecieveCallback() Error inside catch :" & Date.Today.ToString & " " & TimeOfDay)
                MainForm.UpdateList("RecievecallBack error, attempting reconnect..." & client.RemoteEndPoint.ToString())

                MainForm.isRunning = False
                MainForm.DroppedConnection(0)
                'Exit Try

            Finally

                MainForm.isRunning = False

                client.Disconnect(False)
                client.Close()
                client.Dispose()
                Console.WriteLine("Client Connected = " & client.Connected.ToString())
                'MainForm.DroppedConnection(1)
                MainForm.MakeConnection(My.Settings.savedIP, False)

            End Try

        End If
        ' End While
    End Sub 'ReceiveCallback


    Public Shared Sub Send(ByVal client As Socket, ByVal data As String)
        ' Convert the string data to byte data using ASCII encoding.


        Dim byteData As Byte() = Encoding.ASCII.GetBytes(data)

        Try
            If client.Connected = True Then
                client.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), client)
            Else

                MainForm.isRunning = False
                MainForm.DroppedConnection(1)
            End If

        Catch ex As Exception
            MainForm.WriteLog("Async Send() Error :" & Date.Today.ToString & " " & TimeOfDay & " " & ex.Message)
            MainForm.DroppedConnection(1)
        End Try



    End Sub 'Send




    Public Shared Sub SendCallback(ByVal ar As IAsyncResult)
        ' Retrieve the socket from the state object.
        Dim client As Socket = CType(ar.AsyncState, Socket)

        ' Complete sending the data to the remote device.
        Dim bytesSent As Integer = client.EndSend(ar)
        Try
            MainForm.UpdateList("Sent" & bytesSent & " bytes to server.")
            MainForm.WriteLog("SendCallback :" & "Sent " & bytesSent & " bytes to server.")

            ' Signal that all bytes have been sent.
            sendDone.Set()
        Catch ex As Exception
            MainForm.WriteLog("SendCallBack() Error :" & Date.Today.ToString & " " & TimeOfDay & " " & ex.Message)
        End Try


    End Sub 'SendCallback


End Class 'AsynchronousClient

Public Class myBarcodeClass

    Public Shared Function getBarcodeEAN13Image(ByVal barcodeID As String, ByVal filename As String) As System.Drawing.Image
        Dim barcode As System.Drawing.Image
        Try
            Dim settings As Barcode.BarcodeSettings = New Barcode.BarcodeSettings()
            Dim type As String = "EAN13"
            settings.Data2D = barcodeID
            settings.Data = barcodeID
            settings.Type = Spire.Barcode.BarCodeType.EAN13
            Dim fontSize As Short = 25
            Dim font As String = "SimSun"
            font = "MS UI Gogthic  9"

            Dim barHeight As Short = 50
            settings.BarHeight = barHeight
            settings.X = 1.2F
            settings.Unit = GraphicsUnit.Millimeter

            settings.TextFont = New System.Drawing.Font(font, fontSize, FontStyle.Bold)

            settings.ShowText = False
            settings.ShowCheckSumChar = True

            Dim generator As New Barcode.BarCodeGenerator(settings)
            barcode = generator.GenerateImage()
            Dim startY As Integer = barcode.Height * 20 / 100
            Dim minus_height As Integer = barcode.Height * 22 / 100
            barcode = CType(CropImage(barcode, 0, startY, barcode.Width, barcode.Height - minus_height), System.Drawing.Image)
            'barcode.Save(filename)

            Return barcode
        Catch ex As Exception

            MessageBox.Show("getBarcodeEAN13Image")
            MessageBox.Show("myBarcodeClass()" & ex.Message.ToString())
        End Try
        Return barcode
    End Function

    Public Shared Function CropImage(ByVal source As System.Drawing.Image, ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer) As System.Drawing.Bitmap
        Dim bmp As System.Drawing.Bitmap

        Try
            Dim crop As System.Drawing.Rectangle
            crop = New System.Drawing.Rectangle(x, y, width, height)
            bmp = New System.Drawing.Bitmap(crop.Width, crop.Height)
            Dim gr As System.Drawing.Graphics
            gr = System.Drawing.Graphics.FromImage(bmp)
            gr.DrawImage(source, New System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), crop, GraphicsUnit.Pixel)

            Return bmp
        Catch ex As Exception
            MessageBox.Show("CropImage")
            MessageBox.Show(ex.Message.ToString())
        End Try
        Return bmp
    End Function






End Class


Private Sub MainForm_OnFormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    'client.Shutdown(SocketShutdown.Both)
    'client.Close()
End Sub

Private Sub StartStopButton_Click(sender As Object, e As EventArgs) Handles StartStopButton.Click
    My.Settings.savedIP = ServerAddress.Text
    My.Settings.savedPort = PortNumber.Text
    My.Settings.savedTerminalID = TerminalId.Text
    My.Settings.savedPrinter = PrinterDr.Text
    ConnectBtn.Visible = True

    MessageBox.Show("Settings Saved " & PrinterDr.Text)
End Sub

Private Sub ServerResponses_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ServerResponses.SelectedIndexChanged

End Sub

Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
     Handles PrintDocument1.PrintPage
    'PrintDocument1.PrinterSettings.PrinterName = My.Settings.savedPrinter.ToString()
    e.Graphics.DrawString(Drugname1, New Font("Arial", 8), Brushes.Black, 10, 10)
    e.Graphics.DrawString("Exp: " & Expirydate_new, New Font("Arial", 8), Brushes.Black, 10, 20)
    e.Graphics.DrawString("Ds Remaining: " & DsRemaining1, New Font("Arial Bold", 10), Brushes.Black, 10, 30)
    'e.Graphics.DrawString(barCode, New Font("PrecisionID C128 04 Regular", 10), Brushes.Black, 10, 60)
    Dim barCodeImage As Image = Image.FromFile("barcode.bmp")
    e.Graphics.DrawImage(barCodeImage, 180, 30)
    e.HasMorePages = False
    barCodeImage.Dispose()
    UpdateList("Printed Label")
End Sub

Function createBarCodeWithDescription(ByVal barcodeDescription As String, ByVal BarcodeNumber As String, ByVal BarcodeColor As Drawing.Color, ByVal BarcodeSize As Integer, ByVal AddBackGroundColor As Boolean) As Drawing.Bitmap
    Dim textsize As Drawing.SizeF
    Dim stchar As String = String.Empty
    Dim textsize2 As Drawing.SizeF
    Dim col1 As Drawing.Color = BarcodeColor
    Dim col2 As Drawing.Color = BarcodeColor
    Dim k As String = BarcodeNumber
    Dim addStar As String = "*"
    Dim full As String = addStar & BarcodeNumber & addStar
    BarcodeNumber = full
    Dim int As Integer = BarcodeSize / 2
    Dim bc As Drawing.Bitmap = New Drawing.Bitmap(BarcodeSize * 8, BarcodeSize * 3)
    Dim myf As Drawing.Font = New Drawing.Font("Arial", int, New Drawing.FontStyle) ', GraphicsUnit.Point)
    Dim ft As Drawing.Font = New Drawing.Font("PrecisionID C128 04 Regular", BarcodeSize, New Drawing.FontStyle, Drawing.GraphicsUnit.Point)
    Dim g As Drawing.Graphics = Drawing.Graphics.FromImage(bc)
    If AddBackGroundColor = True Then
        g.Clear(Drawing.Color.White)
    End If
    textsize = g.MeasureString(barcodeDescription, myf)
    textsize2 = g.MeasureString(BarcodeNumber, myf)
    g.TextRenderingHint = Drawing.Text.TextRenderingHint.SystemDefault
    g.DrawString(barcodeDescription, myf, New Drawing.SolidBrush(col2), 2, 0)
    g.TextRenderingHint = Drawing.Text.TextRenderingHint.SingleBitPerPixel '
    g.DrawString(BarcodeNumber, ft, New Drawing.SolidBrush(col1), 2, textsize.Height + 2)
    g.TextRenderingHint = Drawing.Text.TextRenderingHint.SystemDefault
    For Each chr As Char In k
        stchar &= chr.ToString & " "
    Next

    g.DrawString(stchar, myf, New Drawing.SolidBrush(col2), 6, textsize.Height + textsize2.Height + 6)
    g.Flush()
    ft.Dispose()
    g.Dispose()
    Return bc
End Function

Private filePath As String
Private fileStream As FileStream
Private streamWriter As StreamWriter

Public Sub OpenFile()
    Dim strPath As String
    strPath = "c:\C51\logs\Error.log"
    If System.IO.File.Exists(strPath) Then
        fileStream = New FileStream(strPath, FileMode.Append, FileAccess.Write)
    Else
        fileStream = New FileStream(strPath, FileMode.Create, FileAccess.Write)
    End If
    streamWriter = New StreamWriter(fileStream)
End Sub

Public Sub WriteLog(ByVal strComments As String)
    OpenFile()
    streamWriter.WriteLine(strComments)
    CloseFile()
End Sub

Public Sub CloseFile()
    streamWriter.Close()
    fileStream.Close()
End Sub

结束班

以下是我在调试器中的内容:正在抛出的异常被捕获在recievecallback()中

    ipaddress is: 127.0.0.1
ConnectCallback() Socket connected to 127.0.0.1:3001
Connected to host
Exception thrown: 'System.Net.Sockets.SocketException' in System.dll
Dropped Connection()Client Connected = False
ipaddress is: 127.0.0.1
Host not available
waiting for plant manager...
Dropped Connection()The thread 0x13a4 has exited with code 0 (0x0).
The thread 0x1a8c has exited with code 0 (0x0).
The program '[8436] SplitePackProject.vshost.exe' has exited with code 0 (0x0).

我真的希望应用程序在强制断开连接后每隔10秒(就像第一次运行和服务器运行时一样)继续尝试连接,但我不能让我的生活让它工作。

有没有人有任何想法?请帮助我理智......

0 个答案:

没有答案
相关问题