'这部分是所有通讯代码
Option Explicit
'--------------------------------------------------------------------------------
Private Declare Function WSAStartup Lib "wsock32.dll" (ByVal wVersionRequested As Integer, lpWSAData As wsadata) As Long
Private Declare Function socket Lib "wsock32.dll" (ByVal af As Long, ByVal socktype As Long, ByVal protocol As Long) As Long
Private Declare Function bind Lib "wsock32.dll" (ByVal s As Long, name As sockaddr, ByVal namelen As Long) As Long
Private Declare Function listen Lib "wsock32.dll" (ByVal s As Long, ByVal backlog As Long) As Long
Private Declare Function accept Lib "wsock32.dll" (ByVal s As Long, addr As sockaddr, addrlen As Long) As Long
Private Declare Function closesocket Lib "wsock32.dll" (ByVal s As Long) As Long
Private Declare Function WSACleanup Lib "wsock32.dll" () As Long
Private Declare PtrSafe Function send Lib "wsock32.dll" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long
Private Declare PtrSafe Function recv Lib "wsock32.dll" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long
'--------------------------------------------------------------------------------
Private Type wsadata
wVersion As Integer
wHighVersion As Integer
szDescription(0 To 255) As Byte
szSystemStatus(0 To 127) As Byte
iMaxSockets As Integer
iMaxUdpDg As Integer
lpVendorInfo As Long
End Type
Private Type sockaddr
sin_family As Integer
sin_port As Integer
sin_addr As Long
sin_zero(0 To 7) As Byte
End Type
Dim serverSocket As Long
Dim clientSocket As Long
Dim serverAddr As sockaddr
Dim clientAddr As sockaddr
Dim clientAddrLen As Long
Dim wsadata As wsadata
Dim result As Long
Public Sub StartTCPServer()
' 初始化 Windows Sockets
result = WSAStartup(&H202, wsadata)
If result <> 0 Then
MsgBox "WSAStartup failed!"
Exit Sub
End If
' 创建套接字
serverSocket = socket(2, 1, 0) ' AF_INET, SOCK_STREAM, IPPROTO_TCP
If serverSocket = 0 Then
MsgBox "Socket creation failed!"
Exit Sub
End If
' 设置服务器地址和端口
serverAddr.sin_family = 2 ' AF_INET
serverAddr.sin_port = htons(12346) ' 设置端口号
' 绑定套接字
result = bind(serverSocket, serverAddr, Len(serverAddr))
' 监听连接
result = listen(serverSocket, 5) ' 允许最多5个连接
DoEvents
If result = 0 Then '可连接
' 等待客户端连接
clientAddrLen = Len(clientAddr)
DoEvents
clientSocket = accept(serverSocket, clientAddr, clientAddrLen)
DoEvents
If clientSocket <> 0 Then
' 在这里处理客户端数据
Dim buffer(2000) As Byte
Dim bytesRead As Long
Dim data As String
Dim Rown As Integer
Rown = 1
DoEvents
100: bytesRead = recv(clientSocket, buffer(0), UBound(buffer) + 1, 0)
If bytesRead > 0 Then
' 从缓冲区中提取接收到的数据
data = VBA.StrConv(buffer, vbUnicode) 'VBA.Left$(buffer, bytesRead)
Sheets("数据").Cells(Rown, 1) = data ' 将数据附加到工作表或进行其他操作---
Erase buffer '清空缓存区数据,防止下次接收重复
Rown = Rown + 1
'If MultiSelectDropdownForm.ExitSub Then Exit Sub
'-----------------------------------------------------------------------------------
' 回复客户端,使用 send 函数发送响应
Dim response As String
response = "Hello, Alredy Recieved!" ' 你的响应消息
' 将响应消息转换为字节数组
Dim responseBytes() As Byte
responseBytes = VBA.StrConv(response, vbFromUnicode)
' 使用 send 函数发送响应
Dim sentBytes As Long
sentBytes = send(clientSocket, responseBytes(0), UBound(responseBytes) + 1, 0)
If sentBytes < 0 Then
' 发送出现错误
MsgBox "send failed with error " & Err.LastDllError
End If
ElseIf bytesRead = 0 Then
' 客户端关闭了连接
CloseTCPServer
Else
' 错误处理
MsgBox "recv failed with error " & Err.LastDllError
CloseTCPServer
End If
DoEvents: GoTo 100 '循环接收
End If
End If
' 关闭服务器套接字和清理
'closesocket serverSocket
'WSACleanup
End Sub
Private Sub CloseTCPServer()
' 关闭客户端连接
closesocket clientSocket
' 关闭服务器套接字和清理
closesocket serverSocket
WSACleanup
End Sub
Private Function htons(value As Integer) As Integer
' 用于处理字节序问题
If (ByteOrder() = 0) Then
htons = value
Else
htons = ((value And &HFF) * 256) + ((value And &HFF00) / 256)
End If
End Function
Private Function ByteOrder() As Integer
' 检查系统的字节序(大端或小端)
Dim test As Integer
test = &H1
If (CVar(VBA.ChrB(test)) = 1) Then
ByteOrder = 0 ' 小端
Else
ByteOrder = 1 ' 大端
End If
End Function
我是用了两台电脑来测试这个通讯,连接和发送接收数据都没有问题,只是执行closeTCP,再重新连接无法连接,只有更换端口号才可以连接,请大家参考一下