Option Explicit
Private Sub Form_Load()
  '設(shè)置本地任意可用端口,這樣系統(tǒng)會自動分配一個未被占用的端口
  Winsock1.LocalPort = 0
  Winsock2.LocalPort = 0
  '設(shè)置通信協(xié)議為 TCP 協(xié)議
  Winsock1.Protocol = sckTCPProtocol
  Winsock2.Protocol = sckTCPProtocol
  '開始監(jiān)聽,等待客戶端連接
  Winsock1.Listen
  Winsock2.Listen
  '初始化PLC地址,IP,端口數(shù)據(jù)
  Open App.Path & "\data\add.ini" For Binary As #1
  Add = StrConv(InputB$(LOF(1), 1), vbUnicode)
  Close #1
  Open App.Path & "\data\ip.ini" For Binary As #1
  ip = StrConv(InputB$(LOF(1), 1), vbUnicode)
  Close #1
  Open App.Path & "\data\port.ini" For Binary As #1
  port = StrConv(InputB$(LOF(1), 1), vbUnicode)
  Close #1
  reg.Text = "0"
  high.Text = "0"
  low.Text = "0"
End Sub
Private Sub SendData_Click()
  '如果 Winsock 處于已連接狀態(tài)
  If Winsock1.State = sckConnected Then
    '構(gòu)造 Modbus TCP 請求數(shù)據(jù)
    Dim PLC_Add As Long
    Dim dataToSend As Integer
    Dim dataToSend1 As Integer
    Dim dataToSend2 As Integer
    'Add PLC起始地址,reg:寄存器地址,high/low高低字節(jié)位(數(shù)據(jù))。
    PLC_Add = Val(Add.Text)
    To_reg = Val(reg.Text)
    To_high = Val(high.Text)
    To_low = Val(low.Text)
    'MODBUSTCP報文
     Dim request As String
    request = Chr(&H0) & Chr(&H1) & Chr(&H0) & Chr(&H0) & Chr(&H0) & Chr(&H6) & Chr(&H1) & Chr(&H6) & Chr(PLC_Add - 40001) & Chr(To_reg) & Chr(To_high) & Chr(To_low)
      '發(fā)送構(gòu)造好的請求數(shù)據(jù)給 PLC
      Winsock1.SendData request
    Exit Sub   
  Else
    '如果未連接到 PLC,彈出消息提示
    MsgBox "Not connected to PLC."
  End If   
End Sub
Private Sub Timer1_Timer()
  '定時器事件,用于周期性檢查連接狀態(tài)并更新界面
  If Winsock1.State = sckConnected Then
    '如果連接成功,將標(biāo)簽的背景色設(shè)置為綠色(十六進(jìn)制顏色值 &HC000&)
    connection.BackColor = &HC000&
  Else
    '如果未連接,將標(biāo)簽的背景色設(shè)置為紅色(十六進(jìn)制顏色值 &HFF&)
    connection.BackColor = &HFF&
  End If    
End Sub
Private Sub Timer2_Timer()
  '定時器事件,用于周期性檢查連接狀態(tài)并重新連接
  If connection.BackColor = &HFF& Then
  '檢查 Winsock 的狀態(tài),如果不是已關(guān)閉狀態(tài)
  If Winsock1.State <> sckClosed Then
    '關(guān)閉當(dāng)前連接,以便重新連接到 PLC
    Winsock1.Close
    '確認(rèn)連接IP地址及端口
    Timer3.Interval = 1
  End If
  If Winsock2.State <> sckClosed Then
    '關(guān)閉當(dāng)前連接,以便重新連接到 PLC
    Winsock2.Close
    '確認(rèn)連接IP地址及端口
    Timer3.Interval = 1
  End If   
    '變量
    Dim plc_ip As String
    Dim plc_port As Integer
    '讀取IP及端口參數(shù)
    plc_ip = ip.Text
    plc_port = port.Text
    '連接到指定的 PLC IP 地址和端口號,這里需替換為實際的 PLC IP 和端口
    Winsock1.Connect plc_ip, plc_port
    Winsock2.Connect plc_ip, plc_port
    '停止IP地址及端口確認(rèn)
    Timer3.Interval = 0
  End If
End Sub
Private Sub Command1_Click()
    '打開通訊設(shè)置窗口
    Form2.Show
End Sub
Private Sub ConnectToPLC_Click()
  '判斷通訊是否啟動連接
  If Timer2.Interval = 0 Then
     '開始連接
    Timer2.Interval = 1
  ElseIf Timer2.Interval = 1 Then
    '判斷通訊是否啟動連接
    If Winsock1.State <> sckClosed Then
    '停止連接
    Timer2.Interval = 0
    '斷開連接
    Winsock1.Close
    Winsock2.Close     
    End If     
  End If
End Sub
Private Sub Timer3_Timer()
    '讀取起始地址
    Open App.Path & "\data\add.ini" For Binary As #1
    '更新起始地址
    Add = StrConv(InputB$(LOF(1), 1), vbUnicode)
    Close #1
    '讀取IP地址
    Open App.Path & "\data\ip.ini" For Binary As #1
    '更新IP地址
    ip = StrConv(InputB$(LOF(1), 1), vbUnicode)
    Close #1
    '讀取端口
    Open App.Path & "\data\port.ini" For Binary As #1
    '更新端口
    port = StrConv(InputB$(LOF(1), 1), vbUnicode)
    Close #1
    '停止更新
    Timer3.Interval = 0
End Sub
Private Sub TCP0_Click(Index As Integer)
  '對齊寄存器地址
  If reg.Text <> 0 Then
    reg.Text = 0
  End If
  '開關(guān)量轉(zhuǎn)換
  If reg.Text = 0 Then
    If low.Text = 0 Then
      low.Text = 1
      SendData_Click
    ElseIf low.Text = 1 Then
      low.Text = 0
      SendData_Click
    End If
  End If
End Sub
Private Sub TCP1_Click(Index As Integer)
  '對齊寄存器地址
  If reg.Text <> 1 Then
    reg.Text = 1
  End If
  '開關(guān)量轉(zhuǎn)換
  If reg.Text = 1 Then
    If low.Text = 0 Then
      low.Text = 1
      SendData_Click
    ElseIf low.Text = 1 Then
      low.Text = 0
      SendData_Click
    End If
  End If
End Sub
Private Sub TCP2_Click(Index As Integer)
  '對齊寄存器地址
  If reg.Text <> 2 Then
    reg.Text = 2
  End If
  '開關(guān)量轉(zhuǎn)換
  If reg.Text = 2 Then
    If low.Text = 0 Then
      low.Text = 1
      SendData_Click
    ElseIf low.Text = 1 Then
      low.Text = 0
      SendData_Click
    End If
  End If
End Sub
Private Sub TCP3_Click(Index As Integer)
  '對齊寄存器地址
  If reg.Text <> 3 Then
    reg.Text = 3
  End If
  '開關(guān)量轉(zhuǎn)換
  If reg.Text = 3 Then
    If low.Text = 0 Then
      low.Text = 1
      SendData_Click
    ElseIf low.Text = 1 Then
      low.Text = 0
      SendData_Click
    End If
  End If
End Sub
Private Sub TCP4_Click(Index As Integer)
  '對齊寄存器地址
  If reg.Text <> 4 Then
    reg.Text = 4
  End If
  '開關(guān)量轉(zhuǎn)換
  If reg.Text = 4 Then
    If low.Text = 0 Then
      low.Text = 1
      SendData_Click
    ElseIf low.Text = 1 Then
      low.Text = 0
      SendData_Click
    End If
  End If
End Sub
Private Sub TCP5_Click(Index As Integer)
  '對齊寄存器地址
  If reg.Text <> 5 Then
    reg.Text = 5
  End If
  '開關(guān)量轉(zhuǎn)換
  If reg.Text = 5 Then
    If low.Text = 0 Then
      low.Text = 1
      SendData_Click
    ElseIf low.Text = 1 Then
      low.Text = 0
      SendData_Click
    End If
  End If
End Sub
Private Sub end_Click()
End
End Sub