1. Gambaran keseluruhan
Semasa memulakan socket server dalam aplikasi Java kami, API java.net menghendaki kami menentukan nombor port percuma untuk didengarkan. Nombor port diperlukan sehingga lapisan TCP dapat mengenal pasti aplikasi yang dimaksudkan untuk data masuk.
Menentukan nombor port secara eksplisit tidak selalu merupakan pilihan yang baik, kerana aplikasi mungkin sudah mempunyainya. Ini akan menyebabkan pengecualian input / output dalam aplikasi Java kami.
Dalam tutorial ringkas ini, kita akan melihat cara memeriksa status port tertentu dan cara menggunakan yang disediakan secara automatik. Kami akan melihat bagaimana ini dapat dilakukan dengan kerangka Java dan Spring biasa. Kami juga akan melihat beberapa pelaksanaan pelayan lain, seperti Tomcat dan Jetty yang tersemat.
2. Memeriksa Status Pelabuhan
Mari lihat bagaimana kita dapat memeriksa apakah port tertentu bebas atau dihuni menggunakan API java.net .
2.1. S pecific Port
Kami akan menggunakan kelas ServerSocket dari API java.net untuk membuat soket pelayan, terikat pada port yang ditentukan. Dalam pembangunnya , ServerSocket menerima nombor port eksplisit. Kelas juga melaksanakan Closeable antara muka, jadi ia boleh digunakan dalam cuba-dengan-sumber untuk secara automatik menutup soket dan membebaskan pelabuhan:
try (ServerSocket serverSocket = new ServerSocket(FREE_PORT_NUMBER)) { assertThat(serverSocket).isNotNull(); assertThat(serverSocket.getLocalPort()).isEqualTo(FREE_PORT_NUMBER); } catch (IOException e) { fail("Port is not available"); }
Sekiranya kita menggunakan port tertentu dua kali, atau sudah dihuni oleh aplikasi lain, konstruktor ServerSocket akan membuang IOException :
try (ServerSocket serverSocket = new ServerSocket(FREE_PORT_NUMBER)) { new ServerSocket(FREE_PORT_NUMBER); fail("Same port cannot be used twice"); } catch (IOException e) { assertThat(e).hasMessageContaining("Address already in use"); }
2.2. P ort Range
Sekarang mari kita periksa bagaimana kita dapat memanfaatkan IOException yang dilemparkan , untuk membuat soket pelayan menggunakan port percuma pertama dari rangkaian nombor port yang diberikan:
for (int port : FREE_PORT_RANGE) { try (ServerSocket serverSocket = new ServerSocket(port)) { assertThat(serverSocket).isNotNull(); assertThat(serverSocket.getLocalPort()).isEqualTo(port); return; } catch (IOException e) { assertThat(e).hasMessageContaining("Address already in use"); } } fail("No free port in the range found");
3. Mencari Pelabuhan Percuma
Menggunakan nombor port eksplisit tidak selalu merupakan pilihan yang baik, jadi mari kita cari kemungkinan untuk memperuntukkan port percuma secara automatik.
3.1. Jawa biasa
Kita boleh menggunakan nombor port khas sifar dalam konstruktor kelas ServerSocket . Hasilnya, API java.net secara automatik akan memperuntukkan port percuma untuk kami:
try (ServerSocket serverSocket = new ServerSocket(0)) { assertThat(serverSocket).isNotNull(); assertThat(serverSocket.getLocalPort()).isGreaterThan(0); } catch (IOException e) { fail("Port is not available"); }
3.2. Kerangka Musim Bunga
Spring framework mengandungi kelas SocketUtils yang dapat kita gunakan untuk mencari port percuma yang tersedia. Pelaksanaan dalamannya menggunakan kelas ServerSocket , seperti yang ditunjukkan dalam contoh sebelumnya:
int port = SocketUtils.findAvailableTcpPort(); try (ServerSocket serverSocket = new ServerSocket(port)) { assertThat(serverSocket).isNotNull(); assertThat(serverSocket.getLocalPort()).isEqualTo(port); } catch (IOException e) { fail("Port is not available"); }
4. Pelaksanaan Pelayan Lain
Sekarang mari kita lihat beberapa pelaksanaan pelayan popular lain.
4.1. Jeti
Jetty adalah pelayan tertanam yang sangat popular untuk aplikasi Java. Ia secara automatik akan memperuntukkan sebuah pelabuhan bebas untuk kita kecuali kita menetapkan ia jelas melalui setPort kaedah yang ServerConnector kelas:
Server jettyServer = new Server(); ServerConnector serverConnector = new ServerConnector(jettyServer); jettyServer.addConnector(serverConnector); try { jettyServer.start(); assertThat(serverConnector.getLocalPort()).isGreaterThan(0); } catch (Exception e) { fail("Failed to start Jetty server"); } finally { jettyServer.stop(); jettyServer.destroy(); }
4.2. Tomcat
Tomcat, pelayan tertanam Java lain yang popular, berfungsi sedikit berbeza. Kami dapat menentukan nombor port eksplisit melalui kaedah setPort kelas Tomcat . Sekiranya kami memberikan nombor port sifar, Tomcat akan secara automatik memperuntukkan port percuma. Namun, jika kita tidak menetapkan nombor port, Tomcat akan menggunakan port lalai 8080. Perhatikan bahawa port Tomcat lalai boleh dihuni oleh aplikasi lain:
Tomcat tomcatServer = new Tomcat(); tomcatServer.setPort(0); try { tomcatServer.start(); assertThat(tomcatServer.getConnector().getLocalPort()).isGreaterThan(0); } catch (LifecycleException e) { fail("Failed to start Tomcat server"); } finally { tomcatServer.stop(); tomcatServer.destroy(); }
5. Kesimpulan
Dalam artikel ini, kami meneroka cara memeriksa status port tertentu. Kami juga membahas mencari port percuma dari pelbagai nombor port dan menjelaskan bagaimana menggunakan port percuma yang diperuntukkan secara automatik.
Dalam contohnya, kami merangkumi kelas ServerSocket asas dari API java.net dan pelaksanaan pelayan popular lain, termasuk Jetty dan Tomcat.
Seperti biasa, kod sumber lengkap boleh didapati di GitHub.