更新時間:2022-04-01 11:05:26 來源:動力節點 瀏覽5174次
Java 有大量有用的網絡庫供您使用。在本文中,我將向您展示如何制作一個可以在您的計算機上運行的簡單 Java 服務器。我們的服務器會做一些事情。我們連接的那一刻,它會打印字符串“Hello!”,它還應該讓我們選擇通過輸入“Peace”來終止連接。本教程的目標是向您展示一些有用的 Java 庫來實現這一點!在創建服務器時,實際上需要考慮 4 個主要步驟。
在實現服務器的核心細節之前,我們需要找到一種方法來確定我們將如何連接到服務器。這很重要,因為它引入了三個核心網絡概念;ip-address,端口和套接字。不要害怕這些術語,我會盡力在下面解釋它們。
IP 地址——在最簡單的形式中,IP 地址只是表示網絡中特定計算機地址的一種奇特方式。這由一個特定的數字表示,例如 192.168.11.11。這是一個唯一的 ID,互聯網上的所有其他機器都可以通過它來識別您的計算機。在我們的例子中,我們將在我們的機器上運行我們的服務器,這意味著連接不必通過互聯網再回到我們的機器,相反,操作系統足夠智能,可以在我們的機器內路由請求,而無需與網絡交互。對于這種情況,有一個專門用于此的特殊 IP 地址;127.0.0.1 或有時稱為 localhost。如果您在 Linux 終端中鍵入ip address,您將看到計算機上的網絡設備列表。第一個是環回設備,此設備允許您計算機中的任何服務與您機器中的其他服務進行通信,您的操作系統將使用環回地址 127.0.0.1 在您的機器內路由它,而不是通過網絡發送它。
端口- 一旦我們有了相關計算機的地址,我們就需要能夠連接到該計算機上我們想要的服務。這就是端口的用武之地。端口就像在提供某些服務的計算機上運行的進程,所以一旦您確定了正確的計算機(使用 IP 地址),我們必須選擇端口才能連接到該計算機中的正確服務。
套接字- 到目前為止,我們可以使用 ip 地址在網絡/互聯網中定位計算機。我們可以使用端口識別我們想要連接到的計算機中的哪個服務,但是我們仍然需要在一臺計算機和我們的目標計算機之間建立連接。這就是套接字的用武之地。套接字可以在網絡中的兩臺計算機之間實現完全的雙向通信。如您所料,套接字需要目標計算機的地址和端口才能創建連接
現在我們已經掌握了網絡的基礎知識,讓我們來創建服務器吧!讓我們從創建連接開始。記住連接是使用套接字創建的。
EC-1:創建連接
公共靜態無效 連接服務器() {
嘗試(服務器套接字服務器套接字= new ServerSocket(9991)) {
套接字連接套接字=服務器套接字。接受();
在 EC-1 中,我們創建了一個方法connectToServer,在這個方法中,我們有一個不完整的嘗試語句,它執行以下操作:
(1)創建一個ServerSocket
(2)指定此服務將在其上運行的端口 9991
(3)接受 ServerSocket 連接!
和沙贊!我們已經建立了我們的聯系,并且至少建立了聯系的基礎。我們還沒有連接到任何東西。在 Java 中,aServerSocket只是等待連接,一旦連接,接收一些任意輸入,處理該輸入,然后返回響應!在我們的例子中,我們的服務器只會回顯您選擇輸入的任何內容!根據 的定義ServerSocket,它需要等待連接,在EC-1中,最后一行接受該連接,我們將其保存在一個名為connectionSocketthat 的變量中,該變量的類型為Socket。
太棒了,所以我們已經完成了連接框架的鋪設。讓我們的服務器交互,允許它在我們連接時進行通信!
為了與我們的服務器來回交互,我們需要一種方法來使用我們剛剛在 EC-1 中設置的連接來來回傳輸信息。一種很好的方法是使用IOStreams,在我們的例子中是 JavaInputStream和OutputStream類。這些將允許進出服務器的雙向通信。讓我們在EC-1中實現它
EC-2:實現 IOStream
...
InputStream inputToServer = connectionSocket .getInputStream();
OutputStream outputFromServer = connectionSocket .getOutputStream();
在EC-2中,我們創建了InputStream一個從上面創建的輸入connectionSocket,我們還創建OutputStream一個從connectionSocket. 輸入流代表我們將發送到服務器的內容,所以它是inputToServer,而輸出代表服務器的輸出。
EC-3:將 IOStreams 轉化為實際可用數據
...
Scanner scanner = new Scanner( inputToServer , "UTF-8");
PrintWriter serverPrintOut = new PrintWriter(new OutputStreamWriter( outputFromServer , "UTF-8"), true);
serverPrintOut .println("你好!輸入和平退出。");
在EC-3中,我們采用IOStreams在EC-2中創建的并使用它們。我們首先創建一個Scanner,掃描器將接收服務器的輸入并將其轉換為服務器可以讀取的形式。然后我們創建一個PrintWriter,PrintWriter它將從服務器獲取輸出并將其打印在我們的屏幕上。創建Scanner和PrintWriter是必不可少的,因為EC-2IOStreams中的單獨僅表示傳輸中的數據,它們不會打印或將數據轉換為服務器和用戶理解的格式。為了讓我們看到我們已經連接到服務器,服務器應該通過打印 Hello! 來通知我們。連接時給我們。
回顧一下,我們現在可以連接到我們的服務器(EC-1) ,通過IOStreams (EC-2)從服務器發送和接收信息,并且可以將流轉換為服務器和用戶的相關輸出(EC-3)。
服務器可以做很多事情,但它仍然不能做一些基本的事情,比如向我們實際打印數據,甚至在客戶端請求時終止連接。我們將在這里實現邏輯。
EC-4: 服務器邏輯
boolean done = false;
while(! done &&掃描儀.hasNextLine()) {
字符串行=掃描儀.nextLine();
serverPrintOut .println("<您的姓名>服務器回顯:" + line );
if( line .toLowerCase().trim().equals("peace")) {
done = true;
}
}
在EC-4中,我們需要一種方法來檢查客戶端是否完成了連接。我們首先創建一個boolean名為的標志done并將其設置為false. 然后我們創建一個 while 循環,它熱切地觀察done值是否變為 true,它還會檢查EC-3Scanner中創建的是否仍然正常運行并且可以接受輸入。
我們服務器的作用是打印回我們輸入的任何內容,Scanner該類檢查用戶是否發送了新行,我們使用該輸入作為服務器的輸出,前綴為“Echo from <Your Name Here> Server: ”.
最后,我們需要找到一種方法來根據客戶端請求實際終止連接。因此,如果客戶端鍵入單詞“peace”,代碼會將 done 標志更改為 true,while 循環條件將不再滿足,它將終止循環和應用程序。
所以我們現在已經制作了簡單的 Hello 服務器,這是一個包含所有代碼在一個方法中的要點!
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
* Written by Martin Ombura Jr. <@martinomburajr>
*/
public class MyServer {
public static void main(String[] args) {
connectToServer();
}
public static void connectToServer() {
//Try connect to the server on an unused port eg 9991. A successful connection will return a socket
try(ServerSocket serverSocket = new ServerSocket(9991)) {
Socket connectionSocket = serverSocket.accept();
//Create Input&Outputstreams for the connection
InputStream inputToServer = connectionSocket.getInputStream();
OutputStream outputFromServer = connectionSocket.getOutputStream();
Scanner scanner = new Scanner(inputToServer, "UTF-8");
PrintWriter serverPrintOut = new PrintWriter(new OutputStreamWriter(outputFromServer, "UTF-8"), true);
serverPrintOut.println("Hello World! Enter Peace to exit.");
//Have the server take input from the client and echo it back
//This should be placed in a loop that listens for a terminator text e.g. bye
boolean done = false;
while(!done && scanner.hasNextLine()) {
String line = scanner.nextLine();
serverPrintOut.println("Echo from <Your Name Here> Server: " + line);
if(line.toLowerCase().trim().equals("peace")) {
done = true;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
是時候投入我們所有的工作并運行這段代碼了。
(1)如何連接
1)從您的 Java IDE 或命令行運行此 Java 應用程序服務器代碼。
2)為了讓您連接到服務器,您需要一個可以讓您執行此操作的工具。在 Linux 和 Mac 上,隨意使用netcat或telnet任何其他您想要的連接協議,如果您沒有它們,請在谷歌搜索如何在您的操作系統版本上安裝它們。對于 Windows,有幾個工具以及winrs. 命令如下
NetCat:這是一種流行的網絡實用程序,用于連接到網站、服務器等。
數控 127.0.0.1 9991
Telnet: Telnet 是一種舊的雙向互聯網連接協議。它非常簡單,將通過未加密的連接發送數據。這意味著您在傳遞敏感信息時應避免使用它。但是對于這個簡單的例子,它是有效的。
遠程登錄 127.0.0.1 9991
Curl: Curl 與上面的兩個有點不同,因為它將以網頁格式連接到服務器。這樣做的缺點是,一旦連接,可能不容易將文本直接發送到 curl,因此您無法通過鍵入“再見”來終止連接。
telnet 127.0.0.1 9991
(2)一旦連接
一旦連接!你應該有一些看起來像這樣的東西。
隨意玩耍并輸入內容,
輸入“peace”關閉連接
當你玩它的時候,嘗試重新啟動連接,添加更多連接等。你會注意到這些重要的點:
(1)這個服務器只能處理一個連接,所以到它的多個連接將被取消。在以后的文章中,我們將讓這個服務器并發,允許它處理多個連接。
(2)如果客戶端,即你,終止連接,套接字關閉,連接中斷,程序結束,這意味著你不能在不重新啟動應用程序的情況下再次連接到服務器。
本文的目的是玩轉 Java 使用的一些很酷的網絡特性!如您所見,可能性是無窮無盡的。我們可以以一種可能基于我們提供的輸入數據執行數學計算的方式對我們的服務器進行編碼,或者我們的服務器可以是數據庫之間的中介,它會執行諸如檢索、驗證、操作或清理數據庫信息之類的操作輸入。機會無窮無盡!
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習