Created
May 8, 2026 07:30
-
-
Save asdf913/6129fc31529aa09f53b49d174ca950bd to your computer and use it in GitHub Desktop.
Get the mulitmap of Process Id and it opened port number.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <dependencies> | |
| <dependency> | |
| <groupId>net.java.dev.jna</groupId> | |
| <artifactId>jna-platform</artifactId> | |
| <version>5.18.1</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>org.apache.commons</groupId> | |
| <artifactId>commons-lang3</artifactId> | |
| <version>3.20.0</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>com.google.guava</groupId> | |
| <artifactId>guava</artifactId> | |
| <version>33.6.0-jre</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>commons-io</groupId> | |
| <artifactId>commons-io</artifactId> | |
| <version>2.22.0</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>org.apache.commons</groupId> | |
| <artifactId>commons-collections4</artifactId> | |
| <version>4.5.0</version> | |
| </dependency> | |
| </dependencies> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import java.nio.charset.StandardCharsets; | |
| import java.nio.file.FileSystems; | |
| import java.util.List; | |
| import java.util.Objects; | |
| import java.util.regex.Matcher; | |
| import java.util.regex.Pattern; | |
| import org.apache.commons.collections4.IterableUtils; | |
| import org.apache.commons.io.IOUtils; | |
| import org.apache.commons.lang3.ArrayUtils; | |
| import org.apache.commons.lang3.ObjectUtils; | |
| import org.apache.commons.lang3.math.NumberUtils; | |
| import com.google.common.collect.LinkedListMultimap; | |
| import com.google.common.collect.Multimap; | |
| import com.sun.jna.Memory; | |
| import com.sun.jna.platform.win32.IPHlpAPI; | |
| import com.sun.jna.platform.win32.IPHlpAPI.MIB_TCPROW_OWNER_PID; | |
| import com.sun.jna.platform.win32.IPHlpAPI.MIB_TCPTABLE_OWNER_PID; | |
| import com.sun.jna.platform.win32.WinError; | |
| import com.sun.jna.ptr.IntByReference; | |
| public class ProcessIdPortMultimap { | |
| public static void main(final String[] args) throws IOException { | |
| // | |
| System.out.println("java.nio.file.FileSystems.getDefault().getClass().getName()=" | |
| + getName(getClass(FileSystems.getDefault()))); | |
| // | |
| System.out.println(getProcessIdPortMultimap()); | |
| // | |
| } | |
| private static Multimap<Integer, Integer> getProcessIdPortMultimap() throws IOException { | |
| // | |
| final String fileSystemClassName = getName(getClass(FileSystems.getDefault())); | |
| // | |
| Multimap<Integer, Integer> multimap = null; | |
| // | |
| if (Objects.equals(fileSystemClassName, "sun.nio.fs.LinuxFileSystem")) { | |
| // | |
| final Process process = new ProcessBuilder("ss", "-tulpn").start(); | |
| // | |
| try (final InputStream is = process != null ? process.getInputStream() : null) { | |
| // | |
| final List<String> lines = IOUtils.readLines(is, StandardCharsets.UTF_8); | |
| // | |
| Pattern p1 = null, p2 = null; | |
| // | |
| String line = null; | |
| // | |
| Matcher matcher = null; | |
| // | |
| Integer processId, port = null; | |
| // | |
| for (int i = 0; i < IterableUtils.size(lines); i++) { | |
| // | |
| processId = port = null; | |
| // | |
| if (find(matcher = matcher(p1 = ObjectUtils.getIfNull(p1, () -> Pattern.compile("(:(\\d+))")), | |
| line = IterableUtils.get(lines, i))) && groupCount(matcher) > 1) { | |
| // | |
| port = NumberUtils.toInt(group(matcher, 2)); | |
| // | |
| } // if | |
| // | |
| if (find(matcher = matcher(p2 = ObjectUtils.getIfNull(p2, () -> Pattern.compile("(pid=(\\d+))")), | |
| line)) && groupCount(matcher) > 1) { | |
| // | |
| processId = NumberUtils.toInt(group(matcher, 2)); | |
| // | |
| } // if | |
| // | |
| if (Boolean.logicalAnd(processId != null, port != null)) { | |
| // | |
| put(multimap = ObjectUtils.getIfNull( | |
| multimap = ObjectUtils.getIfNull(multimap, LinkedListMultimap::create), | |
| LinkedListMultimap::create), processId, port); | |
| // | |
| } // if | |
| // | |
| } // for | |
| // | |
| } // try | |
| // | |
| return multimap; | |
| // | |
| } // if | |
| // | |
| final IPHlpAPI iphlp = Objects.equals(fileSystemClassName, "sun.nio.fs.WindowsFileSystem") ? IPHlpAPI.INSTANCE | |
| : null; | |
| // | |
| final IntByReference dwSize = new IntByReference(0); | |
| // | |
| if (iphlp == null || (iphlp.GetExtendedTcpTable(null, dwSize, true, IPHlpAPI.AF_INET, | |
| IPHlpAPI.TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0)) != WinError.ERROR_INSUFFICIENT_BUFFER) { | |
| // | |
| return null; | |
| // | |
| } // if | |
| // | |
| final Memory buffer = new Memory(dwSize.getValue()); | |
| // | |
| if (iphlp == null || iphlp.GetExtendedTcpTable(buffer, dwSize, true, IPHlpAPI.AF_INET, | |
| IPHlpAPI.TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0) == WinError.NO_ERROR) { | |
| // | |
| final MIB_TCPTABLE_OWNER_PID table = new MIB_TCPTABLE_OWNER_PID(buffer); | |
| // | |
| MIB_TCPROW_OWNER_PID row = null; | |
| // | |
| for (int i = 0; i < table.dwNumEntries; i++) { | |
| // | |
| if (table.table == null || (row = ArrayUtils.get(table.table, i)) == null) { | |
| // | |
| continue; | |
| // | |
| } // if | |
| // | |
| put(multimap = ObjectUtils.getIfNull( | |
| multimap = ObjectUtils.getIfNull(multimap, LinkedListMultimap::create), | |
| LinkedListMultimap::create), row.dwOwningPid, | |
| Integer.valueOf(((row.dwLocalPort & 0xff00) >> 8) | ((row.dwLocalPort & 0xff) << 8))); | |
| // | |
| } // for | |
| // | |
| } // if | |
| // | |
| return multimap; | |
| // ; | |
| // | |
| } | |
| private static String group(final Matcher instance, final int group) { | |
| return instance != null ? instance.group(group) : null; | |
| } | |
| private static int groupCount(final Matcher instance) { | |
| return instance != null ? instance.groupCount() : 0; | |
| } | |
| private static boolean find(final Matcher instance) { | |
| return instance != null && instance.find(); | |
| } | |
| private static Matcher matcher(final Pattern instance, final String input) { | |
| return instance != null ? instance.matcher(input) : null; | |
| } | |
| private static <K, V> void put(final Multimap<K, V> instance, final K key, final V value) { | |
| if (instance != null) { | |
| instance.put(key, value); | |
| } | |
| } | |
| private static String getName(final Class<?> instance) { | |
| return instance != null ? instance.getName() : null; | |
| } | |
| private static Class<?> getClass(final Object instance) { | |
| return instance != null ? instance.getClass() : null; | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Linux
ss(8) - Linux manual page
Microsoft Windows
GetExtendedTcpTable function (iphlpapi.h) - Win32 apps | Microsoft Learn