我真的把头发拉过这一头。 我使用异步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秒(就像第一次运行和服务器运行时一样)继续尝试连接,但我不能让我的生活让它工作。
有没有人有任何想法?请帮助我理智......