#openedge #progress-4gl
#openedge #прогресс -4gl
Вопрос:
Я пытаюсь использовать 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:tempdebug.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?
- Как получить правильную начальную позицию для чтения значения, если я запускаю код на другом компьютере с разрядностью
Я думаю, что теперь вопрос можно закрыть:
https://community.progress.com/s/feed/0D54Q000088eIeASAU?t=1602495359075amp;searchQuery
Спасибо, ребята
Комментарии:
1. Вы говорите, что сейчас пытаетесь использовать GetTcpTable. Но ваш код, похоже, этого не показывает. Вы должны опубликовать код, с которым у вас действительно возникла проблема.
2. Какая строка вашего . Чистый пример выдает вашу ошибку? На 11.6 и 12.2 (оба x64) в Windows 10 я получаю либо порт, когда порт свободен, либо порт 1, если порт используется.
3. @TomBascom Спасибо! Да, вы правы, я должен это сделать, но я понятия не имел о подготовке структуры данных, когда задавал вопрос, поэтому я не вставлял свой код. Теперь я получил ответ от сообщества progress. Кстати: Я впервые задаю вопрос о переполнении стека, что мне делать дальше? Должен ли я вставить ответ на этот вопрос или просто закрыть его?
4. Вы должны, по крайней мере, поддержать nwahmaet, поскольку вы отметили, что его ответ заслуживает «Спасибо». Помимо этого, я бы подумал, что разъяснение исходного вопроса, отражающего то, о чем вы на самом деле спрашивали, вместо того, чтобы показывать код, который связан только косвенно, безусловно, было бы хорошей идеей. Лично я бы предложил тому, кто ответил на ваш вопрос в сообществе progress, также опубликовать этот ответ здесь, чтобы вы могли проголосовать за него и пометить его правильно.
5. @TomBascom многие ценят ваши предложения, я уже отредактировал свой вопрос и уточнил, о чем на самом деле вопрос, о котором я спрашиваю
![]()
Ответ №1:
В документе Microsoft обычно содержатся определения структур (см. https://learn.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcptable ). Как только вы узнаете их — и любые другие, связанные / указывающие на / etc — вы можете создавать и управлять ими, используя MEMPTR
типы данных и различные функции, которые работают с ними: SET-SIZE()
, GET-BYTES()
и GET-POINTER-VALUE()
обычно используются. Об этом есть документ по адресу https://docs.progress.com/bundle/openedge-programmimg-interfaces/page/Shared-Library-and-DLL-Support.html .
Комментарии:
1. Привет, спасибо, теперь я могу получить информацию из возвращаемого значения. Но моя начальная позиция таблицы MIB_TCPROW [ANY_SIZE] является 5-м байтом mTcpTable, похоже, что значение байтов в mTcpTable следует в следующем порядке: dwNumberEntries, таблица MIB_TCPROW [1], таблица MIB_TCPROW [1] … правильно ли это? Извините, я не знаю, как вставить код из-за ограничения символов комментариев