使用Socket進行通信
客戶端通常可使用Socket的構造器來連接到指定服務器Socket通常可使用如下兩個構造器
Socket(InetAddress/String remoteAddress int port)創建連接到指定遠程主機遠程端口的Socket該構造器沒有指定本地地址本地端口默認使用本地主機的默認IP地址默認使用系統動態指定的IP地址
Socket(InetAddress/String remoteAddress int port InetAddress localAddr int localPort)創建連接到指定遠程主機遠程端口的Socket並指定本地IP地址和本地端口號適用於本地主機有多個IP地址的情形
上面兩個構造器中指定遠程主機時既可使用InetAddress來指定也可直接使用String對象來指定但程序通常使用String對象(如)來指定遠程IP當本地主機只有一個IP地址時使用第一個方法更為簡單如下代碼所示
//創建連接到本機端口的Socket
Socket s = new Socket( )
//下面就可以使用Socket進行通信了
…
當程序執行上面代碼中粗體字代碼時該代碼將會連接到指定服務器讓服務器端的ServerSocket的accept()方法向下執行於是服務器端和客戶端就產生一對互相連接的Socket
上面程序連接到遠程主機的IP地址使用的是這個IP地址是一個特殊的地址它總是代表本級的IP地址因為筆者示例程序的服務器端客戶端都是在本機運行所以Socket連接到遠程主機的IP地址使用
當客戶端服務器端產生了對應的Socket之後此時就到了如圖所示的通信示意圖程序無須再區分服務器客戶端而是通過各自的Socket進行通信Socket提供如下兩個方法來獲取輸入流和輸出流
InputStream getInputStream()返回該Socket對象對應的輸入流讓程序通過該輸入流從Socket中取出數據
OutputStream getOutputStream()返回該Socket對象對應的輸出流讓程序通過該輸出流向Socket中輸出數據
看到這兩個方法返回的InputStream和OutputStream讀者應該可以明白Java在設計IO體系上的苦心了不管底層的IO流是怎樣的節點流文件流也好網絡Socket產生的流也好程序都可以將其包裝成處理流從而提供更多方便的處理下面以一個最簡單的網絡通信程序為例來介紹基於TCP協議的網絡通信
下面的服務器程序非常簡單它僅僅建立ServerSocket監聽並使用Socket獲取輸出流輸出
程序清單codes///Serverjava
public class Server
{
public static void main(String[] args)
throws IOException
{
//創建一個ServerSocket用於監聽客戶端Socket的連接請求
ServerSocket ss = new ServerSocket()
//采用循環不斷接受來自客戶端的請求
while (true)
{
//每當接受到客戶端Socket的請求服務器端也對應產生一個Socket
Socket s = ssaccept()
//將Socket對應的輸出流包裝成PrintStream
PrintStream ps = new PrintStream(sgetOutputStream())
//進行普通IO操作
psprintln(您好您收到了服務器的新年祝福!)
//關閉輸出流關閉Socket
psclose()
sclose()
}
}
}
下面的客戶端程序也非常簡單它僅僅使用Socket建立與指定IP指定端口的連接並使用Socket獲取輸入流讀取數據
[] []
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27264.html