"KeepAlive" TCPClient 连接保持打开状态?

"KeepAlive" for TCPClient connection to keep connection open?

有没有办法让 TcpClient 连接持续打开?我有一个应用程序可以让我们的用户扫描纸箱,执行一些数据库更新,并将运输标签发送到用户正在使用的无线打印机(打印机型号为 Zebra QLn420)并从中打印。

应用程序尝试通过 TcpClient 连接与无线打印机保持连接,在将生成的 ZPL 发送到打印机进行打印之前,在整个处理过程中进行多次检查以确保连接良好。

我们遇到了一个偶尔会丢失标签的问题,似乎每当用户停止扫描几分钟,然后又恢复时。然而,跳过标签的情况很少见,因此很难重现(我自己无法复制,但我在仓库里看到过)。

我想知道是否有办法确保连接始终打开(通过 "pinging" 设备),或者是否有办法获得反馈已接收并打印数据。

这是我为确保连接而调用的代码:

Public Function Connect(strIP As String, intPort As Integer) As Boolean
    Try
        'connect to printer via TcpClient, need ip address and port number
        'connects without thread, hangs program for 10-20 seconds if printer is not turned on, replaced with code below to thread the connection and set timeout

        For i As Integer = 1 To 2
            If Not (client IsNot Nothing AndAlso client.Connected) Then
                'uses ClientSocketParameters structure to pass to recursive function ConnectionReturned()
                clntSockParams = New ClientSocketParameters
                clntSockParams.addrs = strIP
                clntSockParams.prt = intPort

                'create client and call BeginConnect (attempts to connect on separate thread until TimeoutTime has elapsed)
                client = New System.Net.Sockets.TcpClient
                client.SendTimeout = 5000
                client.ReceiveTimeout = 5000

                'setup timer with timeout length and start, if timer goes past intTimeoutLength, the Timeout() function is called which closes everything and leaves client = Nothing
                AddHandler TimeoutTime.Elapsed, AddressOf Timeout
                TimeoutTime.Interval = intTimeoutLength
                TimeoutTime.Start()

                client.BeginConnect(strIP, intPort, New AsyncCallback(AddressOf ConnectionReturned), clntSockParams)

                'keeps the program from doing anything else until BeginConnect either succeeds or fails (due to connect on separate thread)
                Do While TimeoutTime.Enabled
                    System.Threading.Thread.Sleep(500)
                Loop
            End If

            'if TimeoutTime is elapsed and client is Nothing, connection didn't happen, throw an error
            If client Is Nothing Then
                blnConnected = False
            Else
                blnConnected = True
                Exit For
            End If
        Next
    Catch ex As Exception
        blnConnected = False
    End Try

    Return blnConnected
End Function

Private Sub ConnectionReturned(ByVal ar As System.IAsyncResult)
    'this method is called from the client.BeginConnect line in Connect(), make sure timer is running
    If TimeoutTime.Enabled Then
        'ensure client is initialized
        If client Is Nothing Then client = New System.Net.Sockets.TcpClient

        'keep calling ConnectionReturned until client.Connected is true
        If client.Connected Then
            TimeoutTime.Stop()
        Else
            Dim actualParameters As ClientSocketParameters = DirectCast(ar.AsyncState, ClientSocketParameters)
            client.BeginConnect(actualParameters.addrs, actualParameters.prt, New AsyncCallback(AddressOf ConnectionReturned), clntSockParams)
        End If
    End If
End Sub

Private Sub Timeout(ByVal sender As Object, ByVal e As EventArgs)
    'this method is only called if TimeoutTime elapsed, which means no connection was made. close the client object if needed, set to Nothing, and stop TimeoutTime
    If TimeoutTime.Enabled Then
        Try
            client.Close()
        Catch ex As Exception
        End Try
        client = Nothing
        TimeoutTime.Stop()
    End If
End Sub

根据这个问题: tcp client in vb.net not receiving the entire data response data from server TcpClient 并不总是保证将所有数据传送到连接的另一端,因此如果有更可靠的连接方法可用,那也值得一试。

如果需要更多信息,请告诉我。谢谢!

最初我通过这个 link 获得了连接代码。从那以后我修改了它,因为如果连接时间更长,它会使应用程序挂起 10-20 秒。这里的代码是用 C# 编写的,我翻译成 VB: Send ZPL Commands via TCP/IP in C#

这是 class 文档的 link: TcpClient Class

这不是明智的解决方案。一个明智的解决方案是:如果由于连接失败,标签没有完全发送到打印机,请建立新连接并发送标签。

Zebra 打印机在 TCP 上有一个超时设置,我认为默认设置为 3 或 5 分钟。要做的第一件事是关闭超时。还有其他原因导致打印机断开连接,因此您也需要处理它。

将其嵌入到您的程序中:

! U1 setvar "wlan.ip.timeout.enable" "off"

确保在该行前后发送 CR/LF。

如果您在格式后发送查询,您可以知道整个格式都已打印到打印机。像下面这样的东西会起作用:

! U1 getvar "device.uptime"