VBA Winsock无法使用更长的端口长度(sin_端口)
我已经创建了下面的Excel VBA代码,它使用Winsock API连接到IP地址,从Excel单元格发送文本字符串,并接收返回的文本字符串 我的代码最初指向IP地址VBA Winsock无法使用更长的端口长度(sin_端口),vba,excel,sockets,winapi,winsock,Vba,Excel,Sockets,Winapi,Winsock,我已经创建了下面的Excel VBA代码,它使用Winsock API连接到IP地址,从Excel单元格发送文本字符串,并接收返回的文本字符串 我的代码最初指向IP地址127.0.0.1,端口80,没有问题。但是,后来我不得不将目标端口更新为60401,这还需要将端口输入变量sinu port更改为Long,因为新端口超过了VBA整数的最大长度。在这些更新之后,代码仍然可以编译,但是Winsock API不会处理任何东西 我认为错误可能与sin_zero变量有关,该变量可能会随着端口长度的增加缓
127.0.0.1
,端口80
,没有问题。但是,后来我不得不将目标端口更新为60401
,这还需要将端口输入变量sinu port
更改为Long,因为新端口超过了VBA整数的最大长度。在这些更新之后,代码仍然可以编译,但是Winsock API不会处理任何东西
我认为错误可能与sin_zero
变量有关,该变量可能会随着端口长度的增加缓冲过多的零?我尝试过调整这个变量并在其他地方诊断代码,但经过几个小时的代码修补后,它仍然无法处理
非常感谢您的帮助。多谢各位
原始代码-端口80-编译和处理成功
Type WSAData
wVersion As Integer
wHighVersion As Integer
szDescription(0 To 255) As Byte
szSystemStatus(0 To 128) As Byte
iMaxSockets As Integer
iMaxUdpDg As Integer
lpVendorInfo As Long
End Type
Type sockaddr_in
sin_family As Integer
sin_port As Integer
sin_addr As Long
sin_zero(0 to 7) As Byte
End Type
Public Declare Function WSAStartup Lib "ws2_32" ( _
ByVal wVersionRequired As Integer, ByRef lpWSAData As WSAData) As Long
Public Declare Function WSAGetLastError Lib "ws2_32" () As Long
Public Declare Function socket Lib "ws2_32" ( _
ByVal af As Long, ByVal socktype As Long, ByVal protocol As Long) As Long
Public Declare Function connect Lib "ws2_32" ( _
ByVal sock As Long, ByRef name As sockaddr_in, ByVal namelen As Integer) As Long
Public Declare Function send Lib "ws2_32" ( _
ByVal sock As Long, ByVal buf As String, ByVal bufLen As Long, ByVal flags As Long) As Long
Public Declare Function recv Lib "ws2_32" ( _
ByVal sock As Long, ByRef buf As Byte, ByVal bufLen As Long, ByVal flags As Long) As Long
Public Declare Function inet_addr Lib "ws2_32" ( _
ByVal s As String) As Long
Public Declare Function htons Lib "ws2_32" ( _
ByVal hostshort As Long) As Long
Function FetchData() As String
Dim iReturn As Long
Dim wsaDat As WSAData
iReturn = WSAStartup(&H202, wsaDat)
If iReturn <> 0 Then
MsgBox "WSAStartup failed", 0, ""
End If
Dim sock As Long
Dim sock1 As Long
Dim lasterr As Long
Dim i As Long
Dim buf(10) As Byte
Dim s As String
Dim j As Integer
sock = socket(2, 1, 6)
Dim addr As sockaddr_in
addr.sin_family = 2
addr.sin_port = htons(80)
addr.sin_addr = inet_addr("127.0.0.1")
i = connect(sock, addr, LenB(addr))
i = send(sock, "*SRTF" & vbCr, 6, 0)
i = recv(sock, buf(0), 10, 0)
For j = 0 To i - 1
s = s & Chr(buf(j))
Next
FetchData = s
End Function
Sub Button2_Click()
Range("C3").Formula = FetchData()
End Sub
类型WSAData
wVersion为整数
wHighVersion为整数
szDescription(0到255)作为字节
szSystemStatus(0到128)作为字节
作为整数的iMaxSockets
iMaxUdpDg作为整数
lpVendorInfo尽可能长
端型
在中键入sockaddr\u
作为整数的sin_族
sin_端口为整数
sin_addr As Long
sin_零(0到7)作为字节
端型
公共声明函数WSAStartup Lib“ws2_32”(_
ByVal wVersionRequired作为整数,ByRef lpWSAData作为WSAData)作为长度
公共声明函数WSAGetLastError Lib“ws2_32”()的长度为
公共声明函数套接字库“ws2_32”(_
ByVal af为长,ByVal socktype为长,ByVal协议为长)为长
公共声明函数连接库“ws2_32”(_
ByVal sock为Long,ByRef name为sockaddr_in,ByVal name为Integer)为Long
公共声明函数send Lib“ws2_32”(_
ByVal袜子一样长,ByVal buf一样长,ByVal bufLen一样长,ByVal标志一样长)一样长
公共声明函数recv Lib“ws2_32”(_
ByVal sock为Long,ByRef buf为Byte,ByVal bufLen为Long,ByVal标志为Long)为Long
公共声明函数inet_addr Lib“ws2_32”(_
ByVal s作为字符串)一样长
公共声明函数htons Lib“ws2_32”(_
ByVal hostshort As Long)As Long
函数FetchData()作为字符串
我转身只要
将wsaDat设置为WSAData
iReturn=WSAStartup(&H202,wsaDat)
如果我满0,那么
MsgBox“WSAStartup失败”,0“
如果结束
暗袜子一样长
暗淡的袜子1一样长
暗淡无光
我想我会坚持多久
Dim buf(10)作为字节
像线一样变暗
作为整数的Dim j
插座=插座(2,1,6)
Dim addr为sockaddr_in
地址:sin_族=2
地址sin_端口=htons(80)
addr.sin\u addr=inet\u addr(“127.0.0.1”)
i=连接(插座、地址、透镜(地址))
i=发送(sock、*SRTF和vbCr,6,0)
i=recv(短袜,buf(0),10,0)
对于j=0到i-1
s=s&Chr(buf(j))
下一个
FetchData=s
端函数
子按钮2\u单击()
范围(“C3”)。公式=FetchData()
端接头
新代码-端口60401-编译,但不处理?
Type WSAData
wVersion As Integer
wHighVersion As Integer
szDescription(0 To 255) As Byte
szSystemStatus(0 To 128) As Byte
iMaxSockets As Integer
iMaxUdpDg As Integer
lpVendorInfo As Long
End Type
Type sockaddr_in
sin_family As Integer
sin_port As Long
sin_addr As Long
sin_zero(0 to 7) As Byte
End Type
Public Declare Function WSAStartup Lib "ws2_32" ( _
ByVal wVersionRequired As Integer, ByRef lpWSAData As WSAData) As Long
Public Declare Function WSAGetLastError Lib "ws2_32" () As Long
Public Declare Function socket Lib "ws2_32" ( _
ByVal af As Long, ByVal socktype As Long, ByVal protocol As Long) As Long
Public Declare Function connect Lib "ws2_32" ( _
ByVal sock As Long, ByRef name As sockaddr_in, ByVal namelen As Integer) As Long
Public Declare Function send Lib "ws2_32" ( _
ByVal sock As Long, ByVal buf As String, ByVal bufLen As Long, ByVal flags As Long) As Long
Public Declare Function recv Lib "ws2_32" ( _
ByVal sock As Long, ByRef buf As Byte, ByVal bufLen As Long, ByVal flags As Long) As Long
Public Declare Function inet_addr Lib "ws2_32" ( _
ByVal s As String) As Long
Public Declare Function htons Lib "ws2_32" ( _
ByVal hostshort As Long) As Long
Function FetchData() As String
Dim iReturn As Long
Dim wsaDat As WSAData
iReturn = WSAStartup(&H202, wsaDat)
If iReturn <> 0 Then
MsgBox "WSAStartup failed", 0, ""
End If
Dim sock As Long
Dim sock1 As Long
Dim lasterr As Long
Dim i As Long
Dim buf(10) As Byte
Dim s As String
Dim j As Integer
sock = socket(2, 1, 6)
Dim addr As sockaddr_in
addr.sin_family = 2
addr.sin_port = htons(60401)
addr.sin_addr = inet_addr("127.0.01")
i = connect(sock, addr, LenB(addr))
i = send(sock, "*SRTF" & vbCr, 6, 0)
i = recv(sock, buf(0), 10, 0)
For j = 0 To i - 1
s = s & Chr(buf(j))
Next
FetchData = s
End Function
Sub Button2_Click()
Range("C3").Formula = FetchData()
End Sub
类型WSAData
wVersion为整数
wHighVersion为整数
szDescription(0到255)作为字节
szSystemStatus(0到128)作为字节
作为整数的iMaxSockets
iMaxUdpDg作为整数
lpVendorInfo尽可能长
端型
在中键入sockaddr\u
作为整数的sin_族
sin_港尽可能长
sin_addr As Long
sin_零(0到7)作为字节
端型
公共声明函数WSAStartup Lib“ws2_32”(_
ByVal wVersionRequired作为整数,ByRef lpWSAData作为WSAData)作为长度
公共声明函数WSAGetLastError Lib“ws2_32”()的长度为
公共声明函数套接字库“ws2_32”(_
ByVal af为长,ByVal socktype为长,ByVal协议为长)为长
公共声明函数连接库“ws2_32”(_
ByVal sock为Long,ByRef name为sockaddr_in,ByVal name为Integer)为Long
公共声明函数send Lib“ws2_32”(_
ByVal袜子一样长,ByVal buf一样长,ByVal bufLen一样长,ByVal标志一样长)一样长
公共声明函数recv Lib“ws2_32”(_
ByVal sock为Long,ByRef buf为Byte,ByVal bufLen为Long,ByVal标志为Long)为Long
公共声明函数inet_addr Lib“ws2_32”(_
ByVal s作为字符串)一样长
公共声明函数htons Lib“ws2_32”(_
ByVal hostshort As Long)As Long
函数FetchData()作为字符串
我转身只要
将wsaDat设置为WSAData
iReturn=WSAStartup(&H202,wsaDat)
如果我满0,那么
MsgBox“WSAStartup失败”,0“
如果结束
暗袜子一样长
暗淡的袜子1一样长
暗淡无光
我想我会坚持多久
Dim buf(10)作为字节
像线一样变暗
作为整数的Dim j
插座=插座(2,1,6)
Dim addr为sockaddr_in
地址:sin_族=2
地址sin_端口=htons(60401)
addr.sin\u addr=inet\u addr(“127.0.01”)
i=连接(插座、地址、透镜(地址))
i=发送(sock、*SRTF和vbCr,6,0)
i=recv(短袜,buf(0),10,0)
对于j=0到i-1
s=s&Chr(buf(j))
下一个
FetchData=s
端函数
子按钮2\u单击()
范围(“C3”)。公式=FetchData()
端接头
您在中更改了sockaddr\u的定义,以便在sin\u端口
字段中使用更大的数据类型。你不能那样做。您需要恢复原始定义以保持与Winsock兼容
您对htons()
的定义也是错误的。ws2_32
中的realhtons()
函数对16位数字操作,而不是您定义的32位数字(htonl()
对32位数字操作)
您遇到的真正问题是VBA的Integer
类型是有符号的,它可以保存的最大值是32767。如果尝试使用更高的值,它将换行为负值
Winsock在
struct中的实际sockaddr\u(和htons()
函数)对sin\u po使用16位无符号类型
Type sockaddr_in
sin_family As Integer
sin_port As Integer
sin_addr As Long
sin_zero(0 to 7) As Byte
End Type
Public Declare Function htons Lib "ws2_32" ( _ ByVal hostshort As Integer) As Integer
addr.sin_port = htons(&HEBF1)
addr.sin_port = htons(-5135)
addr.sin_port = -3605