■101690 / inTopicNo.1) |
VB.NET_SOCKET通信で受信イベントが発生しなくなる |
□投稿者/ KAZUMA (1回)-(2023/03/31(Fri) 20:44:03)
|
分類:[.NET 全般]
vb net netframework4.6.1 vs2019
ある検査機器と、TCP通信でデータを受け取るプログラムを作ったいるのですが、
最初のデータは受け取れるのですが、数十分後に送られてくるデータに
OnConnectRequestが発生しなくなります。
検査機器は、常時接続でコネクションはつながったままです。
wiresharkのパケットキャプチャでログを記録したのですが、
最初のデータ(ENQからEOTまで)を受け取ってから、数十分ごの次のデータ(ENQ)を
検査機器がENQを送信しつづけているのですが、
ENQを受け取ったときに、発生するOnConnectRequestが発生せしないため
ACKを返せず、検査機器はENQを送り続けてしまいます。
・常時接続に対して、下記の組み方はあっているのでしょうか?
・パケットキャプチャでは受け取っているENQが、動作しているEXEが受け取れとれていないとすると、
なにが原因が考えられるでしょうか
なにか、これ調べたらというヒントだけでも頂けたましたら、ありがたいです。
Public Sub New(ByVal ip As String, ByVal port As String, ByVal _mekTable As tableMEK)
frmMain.WriteLog("Program ThreadID:" & Thread.CurrentThread.ManagedThreadId)
Dim myIP As IPAddress = IPAddress.Parse(ip)
ipEndPoint = New IPEndPoint(myIP, Int32.Parse(port))
frame = New Frame
mekTable = _mekTable
listFrameEditer = New List(Of FrameEditer)
dataFrameIndex = 1
End Sub
Public Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
End Sub
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
If Not _disposed Then
If disposing Then
'*** アンマネージリソースの開放
frmMain.WriteLog("process end")
threadMain.Abort()
End If
'*** マネージドリソースの開放
End If
_disposed = True
End Sub
Public Sub Initialize()
frmMain.WriteLog("init ThreadID:" & Thread.CurrentThread.ManagedThreadId)
sock = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, True) 'http://blog.livedoor.jp/nanoris/archives/51820671.html こうしないと同じポートを再度使えない
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, True)
Dim keepAliveTime As UInteger = 60000 '待ち時間 30秒
Dim keepaliveinterval As UInteger = 2000 '間隔
SetKeepAlive(sock, keepalivetime, keepaliveinterval)
sock.Bind(ipEndPoint)
sock.Listen(10)
frmMain.WriteLog("サーバー起動中・・・")
threadMain = New Thread(New ThreadStart(AddressOf Round))
threadMain.Start()
End Sub
''' <summary>
''' TCP KEEPALIVE
''' 参考:https://stackoverflow.com/questions/10292593/how-to-implement-tcp-keepalive-in-vb-net-on-a-tcp-clientsocket
''' </summary>
''' <param name="tcpSocket"></param>
''' <param name="keepAliveTime"></param>
''' <param name="keepAliveInterval"></param>
''' <returns></returns>
Private Shared Function SetKeepAlive(ByRef tcpSocket As Socket, ByVal keepAliveTime As UInteger, ByVal keepAliveInterval As UInteger) As Boolean
' Pack three params into 12-element byte array; not sure about endian issues on non-Intel
Dim SIO_KEEPALIVE_VALS(11) As Byte
Dim keepAliveEnable As UInteger = 1
If (keepAliveTime = 0 Or keepAliveInterval = 0) Then keepAliveEnable = 0
' Bytes 00-03 are 'enable' where '1' is true, '0' is false
' Bytes 04-07 are 'time' in milliseconds
' Bytes 08-12 are 'interval' in milliseconds
Array.Copy(BitConverter.GetBytes(keepAliveEnable), 0, SIO_KEEPALIVE_VALS, 0, 4)
Array.Copy(BitConverter.GetBytes(keepAliveTime), 0, SIO_KEEPALIVE_VALS, 4, 4)
Array.Copy(BitConverter.GetBytes(keepAliveInterval), 0, SIO_KEEPALIVE_VALS, 8, 4)
Try
Dim result() As Byte = BitConverter.GetBytes(CUInt(0)) ' Result needs 4-element byte array?
tcpSocket.IOControl(IOControlCode.KeepAliveValues, SIO_KEEPALIVE_VALS, result)
Catch e As Exception
Return False
End Try
Return True
End Function
Private Sub Round()
frmMain.WriteLog("Round ThreadID:" & Thread.CurrentThread.ManagedThreadId)
hasOpen = True
While True
SocketEvent.Reset()
sock.BeginAccept(New AsyncCallback(AddressOf OnConnectRequest), sock)
SocketEvent.WaitOne()
End While
End Sub
''' <summary>
''' クライアント接続時処理
''' affinionは接続し続ける
''' </summary>
''' <param name="ar"></param>
Private Sub OnConnectRequest(ByVal ar As IAsyncResult)
frmMain.WriteLog("OnConnectRequest ThreadID:" & Thread.CurrentThread.ManagedThreadId)
SocketEvent.[Set]()
Dim listener As Socket = CType(ar.AsyncState, Socket)
Dim handler As Socket = listener.EndAccept(ar)
frmMain.WriteLog(handler.RemoteEndPoint.ToString() & " joined")
Dim state As StateObject = New StateObject()
state.workSocket = handler
handler.BeginReceive(state.buffer, 0, StateObject.BUFFER_SIZE, 0, New AsyncCallback(AddressOf ReadCallback), state)
'データリスト初期化
listData = New List(Of String)
'データ編集を初期化
receivedFrameEditer = New FrameEditer(Me.mekTable)
'コマンドバッファクリア
Me.CmdBuf = Nothing
'*** データ受信イベントを発生 ***
Dim se As New TcpEventArgs
se.ReceivedData = "CON->" & handler.RemoteEndPoint.ToString() & " joined"
RaiseEvent ReceivedData(Me, se)
End Sub
|
|