1. 程式人生 > >【翻譯】java-TCP-socket網絡編程1

【翻譯】java-TCP-socket網絡編程1

底層 停止 bytes 大小 cli 有客 緩沖 什麽 java-tcp

  參考網址:http://tutorials.jenkov.com/java-networking/sockets.html

  我自己學習時做的一個總結,不妥之處請各位大哥指教,小弟先謝過!!

  JavaTCP網絡基礎(Java TCP Networking Basics)

  通常,客戶機打開到服務器的TCP/IP連接。然後客戶機開始與服務器通信。當客戶端完成時,它會再次關閉連接。這裏有一個例子:

技術分享圖片

  客戶端可以通過打開的連接發送多個請求。實際上,客戶機可以發送服務器準備接收的數據的數量。如果願意,服務器也可以關閉連接。

  Java Socket‘s and ServerSocket‘s

  當客戶機想要打開到服務器的TCP/IP連接時,它使用Java套接字
進行操作。套接字被告知要連接什麽IP地址和TCP端口,其余的由Java完成。   如果您想啟動一個服務器,在某個TCP端口上偵聽來自客戶機的傳入連接,則必須使用Java ServerSocket。當客戶端通過客戶端套接字連接到服務器的ServerSocket時,服務器上的socket被分配到該連接。客戶機和服務器現在進行套接字到套接字的通信。   Socket和ServerSocket在後面的文章中有更詳細的介紹。      技術分享圖片

  為了在Java中通過internet(通過TCP/IP)連接到服務器,您需要創建一個Java .net. socket並將其連接到服務器。或者,您也可以使用Java NIO SocketChannel,以防您更喜歡使用Java NIO。

  技術分享圖片

  這個代碼示例在端口80上以IP地址78.46.84.171連接到服務器。該服務器碰巧是我的web服務器(www.jenkov.com),而端口80是web服務器端口。

Socket socket = new Socket("78.46.84.171", 80);

  您還可以使用域名而不是IP地址,如下所示:

Socket socket = new Socket("jenkov.com", 80);

  技術分享圖片

  要寫入Java套接字,必須獲得其OutputStream。這是過程:

Socket socket = new Socket("jenkov.com", 80);//新建一個socket
OutputStream out 
= socket.getOutputStream();//用socket的getOutPutStream獲取輸出 out.write("some data".getBytes());//寫入想要發送的數據 out.flush();//緩沖數據並將其以更大的塊發送 out.close();//發完了就關閉流 socket.close();//全部交互結束,關閉socket。
  就是這麽簡單!   當您非常非常希望將數據通過internet發送到服務器時,不要忘記調用flush()。操作系統中的底層TCP/IP實現可以緩沖數據並將其以更大的塊發送,以適應TCP/IP數據包的大小。   技術分享圖片

  要從Java套接字讀取數據,需要獲得其InputStream。這是過程:

Socket socket = new Socket("jenkov.com", 80);//新建一個socket
InputStream in = socket.getInputStream();//用socket的getInputStream獲取輸入

int data = in.read();//讀取數據
//... read more data...

in.close();//關閉輸入流
socket.close();//關閉socket連接
  很簡單,對吧?   請記住,在套接字的InputStream返回-1之前,您不能總是從它讀取數據,就像在讀取文件時一樣。原因是只有當服務器關閉連接時才返回-1。但是服務器可能並不總是關閉連接。也許您希望通過同一連接發送多個請求。在這種情況下,關閉連接是非常愚蠢的。   反,您必須知道從套接字的InputStream讀取多少字節。這可以通過告訴服務器它正在發送多少字節來完成,或者通過查找一個特殊的數據結束字符來完成。   我發現這裏很容易弄混,說了這麽多,那到底是哪裏讀到哪裏???

  技術分享圖片

  考慮上面的代碼,應該思路就清晰了。

  代理服務器:

  技術分享圖片

    

  上面看懂了,,,那我接著說。。。。

  技術分享圖片

  為了實現通過TCP/IP偵聽來自客戶機的傳入連接的Java服務器,您需要使用Java .net. serversocket。如果您喜歡使用Java NIO而不是Java聯網(標準API),那麽您還可以使用ServerSocketChannel而不是Java .net. serversocket。

  技術分享圖片

  下面是一個簡單的代碼示例,它創建了一個監聽端口9000的ServerSocket:

ServerSocket serverSocket = new ServerSocket(9000);

技術分享圖片

  監聽到來的連接請求:

  為了接受傳入的連接,必須調用ServerSocket.accept()方法。accept()方法返回一個套接字,其行為與普通Java套接字類似。以下是它的樣子:

ServerSocket serverSocket = new ServerSocket(9000);//創建serverSocket

boolean isStopped = false;//假如沒有停止傳輸,持續監聽
while(!isStopped){
    Socket clientSocket = serverSocket.accept();//監聽

    //do something with clientSocket
}
  對於對accept()方法的每次調用,只打開一個傳入連接。   此外,只能在運行服務器的線程調用accept()時接受傳入的連接。線程在此方法之外執行時,沒有客戶機可以連接。因此,“接受”線程通常將傳入的連接(套接字的)傳遞給工作線程池,然後工作線程池與客戶機通信。有關多線程服務器設計的更多信息,請參閱教程跟蹤Java多線程服務器。

  技術分享圖片

  一旦客戶端請求完成,並且沒有從該客戶端接收到進一步的請求,您必須關閉該套接字,就像關閉普通的客戶端套接字一樣。這是通過調用:

socket.close();

  一旦這臺服務器被關閉了,你還得關閉ServerSocket。這是通過下面的代碼:

serverSocket.close();

  那麽就先寫到這裏。

【翻譯】java-TCP-socket網絡編程1