openedge - 如何使用 Windows API 'GetTcpTable' 找到可用的 tcp 端口?
问题描述
我正在尝试使用 windows api 'GetTcpTable',但我不知道如何准备数据结构 'PMIB_TCPTABLE' 并从中获取返回值。
PROCEDURE GetTcpTable EXTERNAL "Iphlpapi":U:
DEFINE OUTPUT PARAMETER mTcpTable AS HANDLE TO MEMPTR. // the API expects a pointer, so use HANDLE TO syntax to pass one
DEFINE INPUT-OUTPUT PARAMETER SizePointer AS HANDLE TO LONG.
DEFINE INPUT PARAMETER Order AS LONG.
DEFINE RETURN PARAMETER IPHLPAPI_DLL_LINKAGE AS LONG.
END PROCEDURE.
DEFINE VARIABLE mTcpTable AS MEMPTR NO-UNDO.
DEFINE VARIABLE SizePointer AS INT NO-UNDO.
DEFINE VARIABLE Order AS INT NO-UNDO.
DEFINE VARIABLE IPHLPAPI AS INT NO-UNDO.
DEFINE VARIABLE mTempValue AS MEMPTR NO-UNDO.
DEFINE VARIABLE dwNumEntries AS INT NO-UNDO.
DEFINE VARIABLE dwState AS INT NO-UNDO.
DEFINE VARIABLE dwLocalAddr AS INT64 NO-UNDO.
DEFINE VARIABLE dwLocalPort AS INT NO-UNDO.
DEFINE VARIABLE dwRemoteAddr AS INT64 NO-UNDO.
DEFINE VARIABLE dwRemotePort AS INT NO-UNDO.
DEFINE VARIABLE ix AS INTEGER NO-UNDO.
SizePointer = 4.
Order = 1.
SET-SIZE(mTcpTable) = SizePointer.
RUN GetTcpTable(OUTPUT mTcpTable, INPUT-OUTPUT SizePointer,INPUT Order, OUTPUT IPHLPAPI). //get ERROR_INSUFFICIENT_BUFFER and know the real buffer now
MESSAGE "IPHLPAPI is " IPHLPAPI SKIP // ERROR_INSUFFICIENT_BUFFER = 122
"SizePointer is " SizePointer SKIP
VIEW-AS ALERT-BOX.
SET-SIZE(mTcpTable) = 0.
SET-SIZE(mTcpTable) = SizePointer.
RUN GetTcpTable(OUTPUT mTcpTable, INPUT-OUTPUT SizePointer,INPUT Order, OUTPUT IPHLPAPI).
MESSAGE "IPHLPAPI is " IPHLPAPI SKIP // NO_ERROR = 0
"SizePointer is " SizePointer SKIP
GET-LONG(mTcpTable,1) SKIP //dwNumEntries
VIEW-AS ALERT-BOX.
IF IPHLPAPI = 0 THEN DO:
dwNumEntries = GET-LONG(mTcpTable,1).
OUTPUT TO VALUE ("C:\temp\debug.txt") UNBUFFERED.
DO ix = 0 TO dwNumEntries - 1.
dwState = GET-UNSIGNED-LONG(mTcpTable,5 + ix * 20). // get value of dwState
dwLocalAddr = GET-UNSIGNED-LONG(mTcpTable,9 + ix * 20). // get value of dwLocalAddr
SET-SIZE(mTempValue) = 2.
PUT-BYTE(mTempValue,2) = GET-UNSIGNED-SHORT(mTcpTable,13 + ix * 20).
PUT-BYTE(mTempValue,1) = GET-UNSIGNED-SHORT(mTcpTable,14 + ix * 20).
dwLocalPort = GET-UNSIGNED-SHORT(mTempValue,1). // get value of dwLocalPort, The maximum size of an IP port number is 16 bits, so only the lower 16 bits should be used. The upper 16 bits may contain uninitialized data.
SET-SIZE(mTempValue) = 0.
dwRemoteAddr = GET-UNSIGNED-LONG(mTcpTable,17 + ix * 20). // get value of dwRemoteAddr
SET-SIZE(mTempValue) = 2.
PUT-BYTE(mTempValue,2) = GET-UNSIGNED-SHORT(mTcpTable,21 + ix * 20).
PUT-BYTE(mTempValue,1) = GET-UNSIGNED-SHORT(mTcpTable,22 + ix * 20).
dwRemotePort = GET-UNSIGNED-SHORT(mTempValue,1). // get value of dwRemotePort, The maximum size of an IP port number is 16 bits, so only the lower 16 bits should be used. The upper 16 bits may contain uninitialized data.
SET-SIZE(mTempValue) = 0.
PUT UNFORMATTED dwState "~t" dwLocalAddr "~t" dwLocalPort "~t" dwRemoteAddr "~t" dwRemotePort "~r".
END.
OUTPUT CLOSE.
END.
SET-SIZE(mTcpTable) = 0.
- 有没有更好的方法来获得低 16 位?我不确定为什么我需要将字节以相反的顺序放入 mTempValue,它是否与 x86 PC 的小端有关?
- 如果我在不同位数的计算机上运行代码,如何获得正确的起始位置来读取值
我认为这个问题现在可以结束了:
https
://community.progress.com/s/feed/0D54Q000088eIeASAU?t=1602495359075&searchQuery
谢谢你们 :)
解决方案
Microsoft 的文档通常具有结构的定义(请参阅https://docs.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcptable)。一旦你知道了这些 - 以及任何其他相关/指向/等 - 你可以使用MEMPTR
数据类型和对它们进行操作的各种函数来创建和操作它们:SET-SIZE()
,GET-BYTES()
并且GET-POINTER-VALUE()
通常使用。在https://docs.progress.com/bundle/openedge-programmimg-interfaces/page/Shared-Library-and-DLL-Support.html上有关于此的文档。
推荐阅读
- sql - 如何从外部 api 获取数据并将其存储在本地数据库中?(javascript)
- python-3.x - Python pypyodbc ValueError: microsecond must be in 0..999999
- android - Making ListView Clickable React Native
- javascript - Leaflet JS - external controls
- google-apps-script - 必须在每个新副本上启用 Admin SDK
- javascript - 检索两个频道的消息列表
- node.js - 访问 AzureBotStorage 中的所有用户数据
- oauth-2.0 - Maintaining oath callback URLs
- opencv - 为什么 MEAN SHIFT + ORB 没有检测到(所有)多个对象?
- version-control - RTC SCM 查询工作区退出代码