本文節選自:http://www.builder.com.cn/2008/0414/813590.shtml
什麼是通訊端(Socket)?
Network API是典型的用於基於TCP/IP網路Java程式與其他程式通訊,Network API依靠Socket進行通訊。
Socket可以看成在兩個程式進行通訊串連中的一個端點,一個程式將一段資訊寫入Socket中,該Socket將這段資訊發送給另外一個Socket中,1
我們來分析一1,Host A上的程式A將一段資訊寫入Socket中,Socket的內容被Host A的網路管理軟體訪問,並將這段資訊通過Host A的網路介面卡發送到Host B,Host B的網路介面卡接收到這段資訊後,傳送給Host B的網路管理軟體,網路管理軟體將這段資訊儲存在Host B的Socket中,然後程式B才能在Socket中閱讀這段資訊。
基於TCP/IP網路中的每一個主機均被賦予了一個唯一的IP地址,IP地址是一個32位的不帶正負號的整數,由於沒有轉變成二進位,因此通常以小數點分隔,如:198.163.227.6,正如所見IP地址均由四個部分組成,每個部分的範圍都是0-255,以表示8位地址。
每一個基於TCP/IP網路通訊的程式都被賦予了唯一的連接埠和連接埠號碼,連接埠是一個資訊緩衝區,用於保留Socket中的輸入/輸出資訊,連接埠號碼是一個16位不帶正負號的整數,範圍是0-65535,以區別主機上的每一個程式(連接埠號碼就像房屋中的房間號),低於256的短口號保留給標準應用程式,比如pop3的連接埠號碼就是110,每一個通訊端都組合進了IP地址、連接埠、連接埠號碼,這樣形成的整體就可以區別每一個通訊端t。
Java的Socket類
當客戶程式需要與伺服器程式通訊的時候,客戶程式在客戶機建立一個socket對象。兩個常用的建構函式是 Socket(InetAddress addr, int port) 和 Socket(String host, int port)。對於第一個InetAddress子類對象通過addr參數獲得伺服器主機的IP地址,對於第二個函數host參數包被分配到InetAddress對象中,如果沒有IP地址與host參數相一致,那麼將拋出UnknownHostException異常對象。兩個函數都通過參數port獲得伺服器的連接埠號碼。假設已經建立串連了,網路API將在用戶端基於Socket的流通訊端中捆綁客戶程式的IP地址和任意一個連接埠號碼,否則兩個函數都會拋出一個IOException對象。
如果建立了一個Socket對象,那麼它可能通過調用Socket的 getInputStream()方法從服務程式獲得輸入資料流讀傳送來的資訊,也可能通過調用Socket的 getOutputStream()方法獲得輸出流來發送訊息。在讀寫活動完成之後,客戶程式調用close()方法關閉流和流通訊端,下面的代碼建立了一個服務程式主機地址為198.163.227.6,連接埠號碼為13的Socket對象,然後從這個新建立的Socket對象中讀取輸入資料流,然後再關閉流和Socket對象。
Socket s = new Socket ("198.163.227.6", 13);InputStream is = s.getInputStream ();// Read from the stream.is.close ();s.close ();
Java執行個體:
// SSClient.javaimport java.io.*;import java.net.*;class SSClient{ public static void main (String [] args) { String host = "localhost"; // If user specifies a command-line argument, that argument // represents the host name. if (args.length == 1) host = args [0]; BufferedReader br = null; PrintWriter pw = null; Socket s = null; try{ // Create a socket that attempts to connect to the server // program on the host at port 10000. s = new Socket (host, 10000); // Create an input stream reader that chains to the socket's // byte-oriented input stream. The input stream reade // converts bytes read from the socket to characters. The // conversion is based on the platform's default character // set. InputStreamReader isr; isr = new InputStreamReader (s.getInputStream ()); // Create a buffered reader that chains to the input stream // reader. The buffered reader supplies a convenient method // for reading entire lines of text. br = new BufferedReader (isr); // Create a print writer that chains to the socket's byte- // oriented output stream. The print writer creates an // intermediate output stream writer that converts // characters sent to the socket to bytes. The conversion // is based on the platform's default character set. pw = new PrintWriter (s.getOutputStream (), true); // Send the DATE command to the server. pw.println ("DATE"); // Obtain and print the current date/time. System.out.println (br.readLine ()); // Send the PAUSE command to the server. This allows several // clients to start and verifies that the server is spawning // multiple threads. pw.println ("PAUSE"); // Send the DOW command to the server. pw.println ("DOW"); // Obtain and print the current day of week. System.out.println (br.readLine ()); // Send the DOM command to the server. pw.println ("DOM"); // Obtain and print the current day of month. System.out.println (br.readLine ()); // Send the DOY command to the server. pw.println ("DOY"); // Obtain and print the current day of year. System.out.println (br.readLine ()); } catch (IOException e) { // Exception process... } finally { try{ if (br != null) br.close (); if (pw != null) pw.close (); if (s != null) s.close (); } catch (IOException e){ // Exception process... } } }}
SSClient建立了一個Socket對象與運行在主機連接埠10000的服務程式聯絡,主機的IP地址由host變數確定。
SSClient將獲得Socket的輸入輸出資料流,圍繞BufferedReader的輸入資料流和PrintWriter的輸出資料流對字串進行讀寫操作就變得非常容易,SSClient個服務程式發出各種date/time命令並得到響應,每個響應均被列印,一旦最後一個響應被列印,將執行Try/Catch/Finally結構的Finally子串,Finally子串將在關閉Socket之前關閉BufferedReader
和 PrintWriter。