前言
使用基于tcp 協議的雙向通信時,網絡中的兩個應用程序之間必須首先建立一個連接,這兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。
建立網絡通信連接至少要一對端口號(socket)。socket本質是編程接口(api),對tcp/ip的封裝,tcp/ip也要提供可供程序員做網絡開發所用的接口,這就是socket編程接口;http是轎車,提供了封裝或者顯示數據的具體形式;socket是發動機,提供了網絡通信的能力。
socket的英文原義是“孔”或“插座”。作為bsd unix的進程通信機制,取后一種意思。通常也稱作"套接字",用于描述ip地址和端口,是一個通信鏈的句柄,可以用來實現不同虛擬機或不同計算機之間的通信。在internet上的主機一般運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個socket,并綁定到一個端口上,不同的端口對應于不同的服務。socket正如其英文原意那樣,像一個多孔插座。一臺主機猶如布滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電, 有的提供110伏交流電,有的則提供有線電視節目。 客戶軟件將插頭插到不同編號的插座,就可以得到不同的服務。
使用 socket 的通信模式
java.net 程序包將基于tcp 通信的socket 封裝為兩個類:類socket 表達了一個用于建立tcp 連接的socket,該socket 既可由客戶程序使用,也可由服務程序
使用;類serversocket 則是一個服務端專門監聽客戶程序連接請求的socket 的抽象,僅在服務程序中使用。
socket通信過程
服務器端:
① 創建serversocket對象,綁定監聽端口
② 通過accept()方法監聽客戶端請求
③ 連接建立后,通過輸入流讀取客戶端發送的請求信息
④ 通過輸出流向客戶端發送響應信息
⑤ 關閉連接
客戶端:
① 創建socket對象,指明需要連接的服務器的地址和端口號
② 連接建立后,通過輸出流想服務器端發送請求信息
③ 通過輸入流獲取服務器響應的信息
④ 關閉連接
單線程服務程序代碼
服務端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
import java.net.*; import java.io.*; public class echoserver { public static void main(string[] args) throws ioexception { if (args.length != 1 ) { system.out.println( "用法:echoserver <端口號>" ); return ; } // 監聽客戶程序的連接請求 serversocket listensocket = new serversocket(integer.parseint(args[ 0 ])); system.out.println( "服務程序正在監聽端口" + args[ 0 ]); socket socket = listensocket.accept(); // 從與客戶程序的新建連接獲取輸入流和輸出流 printwriter out = new printwriter(socket.getoutputstream(), true ); bufferedreader in = new bufferedreader( new inputstreamreader (socket.getinputstream())); // 從客戶端讀取數據,并寫回數據的加工結果 string message; while ((message = in.readline()) != null ) { system.out.println( "收到請求:" + message); out.println(message.touppercase()); } // 關閉連接 out.close(); in.close(); socket.close(); listensocket.close(); } } |
客戶端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
import java.net.*; import java.io.*; public class echoclient { public static void main(string[] args) throws exception { if (args.length != 2 ) { system.out.println( "用法:echoclient <主機名> <端口號>" ); return ; } // 建立連接并打開相關聯的輸入流和輸出流 socket socket = new socket(args[ 0 ], integer.parseint(args[ 1 ])); system.out.println( "當前socket信息:" + socket); printwriter out = new printwriter(socket.getoutputstream(), true ); bufferedreader in = new bufferedreader( new inputstreamreader (socket.getinputstream())); // 將控制臺輸入的字符串發送給服務端,并顯示從服務端獲取的處理結果 bufferedreader stdin = new bufferedreader( new inputstreamreader (system.in)); string userinput; while ((userinput = stdin.readline()) != null ) { out.println(userinput); system.out.println( "返回:" + in.readline()); } stdin.close(); // 關閉連接 out.close(); in.close(); socket.close(); } } |
運行結果示例(基于windows)
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/zhaokx3/article/details/52513019