TCP的Java支持 協(xié)議相當(dāng)于相互通信的程序間達(dá)成的一種約定,它規(guī)定了分組報(bào)文的結(jié)構(gòu)、交換方式、包含的意義以及怎樣對(duì)報(bào)文所包含的信息進(jìn)行解析,TCP/IP協(xié)議族有IP協(xié)議、TCP協(xié)議和UDP協(xié)議。現(xiàn)在TCP/IP協(xié)議族中的主要socket類型為流套接字(使用TCP協(xié)議)和數(shù)據(jù)報(bào)套接字(使用UDP協(xié)議)。 TCP協(xié)議提供面向連接的服務(wù),通過(guò)它建立的是可靠地連接。Java為T(mén)CP協(xié)議提供了兩個(gè)類:Socket類和ServerSocket類。一個(gè)Socket實(shí)例代表了TCP連接的一個(gè)客戶端,而一個(gè)ServerSocket實(shí)例代表了TCP連接的一個(gè)服務(wù)器端,一般在TCP Socket編程中,客戶端有多個(gè),而服務(wù)器端只有一個(gè),客戶端TCP向服務(wù)器端TCP發(fā)送連接請(qǐng)求,服務(wù)器端的ServerSocket實(shí)例則監(jiān)聽(tīng)來(lái)自客戶端的TCP連接請(qǐng)求,并為每個(gè)請(qǐng)求創(chuàng)建新的Socket實(shí)例,由于服務(wù)端在調(diào)用accept() 等待客戶端的連接請(qǐng)求時(shí)會(huì)阻塞,直到收到客戶端發(fā)送的連接請(qǐng)求才會(huì)繼續(xù)往下執(zhí)行代碼,因此要為每個(gè)Socket連接開(kāi)啟一個(gè)線程。服務(wù)器端要同時(shí)處理ServerSocket實(shí)例和Socket實(shí)例,而客戶端只需要使用Socket實(shí)例。另外,每個(gè)Socket實(shí)例會(huì)關(guān)聯(lián)一個(gè)InputStream和OutputStream對(duì)象,我們通過(guò)將字節(jié)寫(xiě)入套接字的OutputStream來(lái)發(fā)送數(shù)據(jù),并通過(guò)從InputStream來(lái)接收數(shù)據(jù)。 TCP連接的建立步驟: 客戶端向服務(wù)器端發(fā)送連接請(qǐng)求后,就被動(dòng)地等待服務(wù)器的響應(yīng)。典型的TCP客戶端要經(jīng)過(guò)下面三步操作: 1. 創(chuàng)建一個(gè)Socket實(shí)例:構(gòu)造函數(shù)向指定的遠(yuǎn)程主機(jī)和端口建立一個(gè)TCP連接; 2. 通過(guò)套接字的I/O流與服務(wù)端通信; 3. 使用Socket類的close方法關(guān)閉連接。 服務(wù)端的工作是建立一個(gè)通信終端,并被動(dòng)地等待客戶端的連接。典型的TCP服務(wù)端執(zhí)行如下操作: 1. 創(chuàng)建ServerSocket對(duì)象,綁定并監(jiān)聽(tīng)端口 2. 通過(guò)accept監(jiān)聽(tīng)客戶端的請(qǐng)求 3. 建立連接后,通過(guò)輸出輸入流進(jìn)行讀寫(xiě)操作 4. 關(guān)閉相關(guān)資源 一個(gè)程序?yàn)榉?wù)端,建立TCP服務(wù)端套接字。 java源程序如下: import java.io.DataInputStream;//導(dǎo)入DataInputStream類import java.io.DataOutputStream;//導(dǎo)入DataOutputStreamimport java.io.IOException;//導(dǎo)入IOException類import java.net.Socket;//導(dǎo)入Socket類import java.util.Scanner;//導(dǎo)入Scanner類/** * 注意用到的輸入輸出流DataInputStream和DataOutputStream,成對(duì)出現(xiàn),最好用字節(jié)流 */// 客戶端類public class ChatClient {//創(chuàng)建公共類 private String host = 'localhost';// 默認(rèn)連接到本機(jī) private int port = 8189;// 默認(rèn)連接到端口8189 public ChatClient() { } // 連接到指定的主機(jī)和端口 public ChatClient(String host, int port) {//構(gòu)造方法 this.host = host;//將構(gòu)造方法的參數(shù)host傳遞給類變量host this.port = port;//將構(gòu)造方法的參數(shù)port傳遞給類變量port } public void chat() {//chat方法 try { // 連接到服務(wù)器 Socket socket = new Socket(host, port);//創(chuàng)建Socket類對(duì)象 try { DataInputStream in = new DataInputStream(socket .getInputStream());// 讀取服務(wù)器端傳過(guò)來(lái)信息的DataInputStream DataOutputStream out = new DataOutputStream(socket .getOutputStream());// 向服務(wù)器端發(fā)送信息的DataOutputStream Scanner scanner = new Scanner(System.in);// 裝飾標(biāo)準(zhǔn)輸入流,用于從控制臺(tái)輸入 while (true) { String send = scanner.nextLine();//讀取控制臺(tái)輸入的內(nèi)容 System.out.println('客戶端:' + send);//輸出鍵盤(pán)輸出內(nèi)容提示 ,也就是客戶端向服務(wù)器端發(fā)送的消息 // 把從控制臺(tái)得到的信息傳送給服務(wù)器 out.writeUTF('客戶端:' + send);//將客戶端的信息傳遞給服務(wù)器 String accpet = in.readUTF();// 讀取來(lái)自服務(wù)器的信息 System.out.println(accpet);//輸出來(lái)自服務(wù)器的信息 } } finally { socket.close();//關(guān)閉Socket監(jiān)聽(tīng) } } catch (IOException e) {//捕獲異常 e.printStackTrace(); } } public static void main(String[] args) {//主程序方法 new ChatClient().chat();//調(diào)用chat方法 }}
另外一個(gè)程序?yàn)榭蛻舳?,建立TCP客戶端套接字。 java源程序如下: import java.io.DataInputStream; //導(dǎo)入 DataInputStream類import java.io.DataOutputStream;//導(dǎo)入DataOutputStream類 import java.io.IOException;//導(dǎo)入IOException類import java.net.ServerSocket;//導(dǎo)入ServerSocket類 import java.net.Socket; //導(dǎo)入Socket 類 import java.util.Scanner; //導(dǎo)入Scanner類/** * 模擬qq聊天功能: 實(shí)現(xiàn)客戶端與服務(wù)器(一對(duì)一)的聊天功能,客戶端首先發(fā)起聊天,輸入的內(nèi)容在服務(wù)器端和客戶端顯示, * 然后服務(wù)器端也可以輸入信息,同樣信息也在客戶端和服務(wù)器端顯示 */ // 服務(wù)器類 public class ChatServer {//ChatServer類 private int port = 8189;// 默認(rèn)服務(wù)器端口 public ChatServer() { } // 創(chuàng)建指定端口的服務(wù)器 public ChatServer(int port) {//構(gòu)造方法 this.port = port;//將方法參數(shù)賦值給類參數(shù) } // 提供服務(wù) public void service() {//創(chuàng)建service方法 try {// 建立服務(wù)器連接 ServerSocket server = new ServerSocket(port);//創(chuàng)建 ServerSocket類 Socket socket = server.accept();// 等待客戶連接 try { DataInputStream in = new DataInputStream(socket .getInputStream());// 讀取客戶端傳過(guò)來(lái)信息的DataInputStream DataOutputStream out = new DataOutputStream(socket .getOutputStream());// 向客戶端發(fā)送信息的DataOutputStream Scanner scanner = new Scanner(System.in);//從鍵盤(pán)接受數(shù)據(jù) while (true) { String accpet = in.readUTF();// 讀取來(lái)自客戶端的信息 System.out.println(accpet);//輸出來(lái)自客戶端的信息 String send = scanner.nextLine();//nextLine方式接受字符串 System.out.println('服務(wù)器:' + send);//輸出提示信息 out.writeUTF('服務(wù)器:' + send);//把服務(wù)器端的輸入發(fā)給客戶端 } } finally {// 建立連接失敗的話不會(huì)執(zhí)行socket.close(); socket.close();//關(guān)閉連接 server.close();//關(guān)閉 } } catch (IOException e) {//捕獲異常 e.printStackTrace(); } } public static void main(String[] args) {//主程序方法 new ChatServer().service();//調(diào)用 service方法 } }
注:在運(yùn)行前要建立兩個(gè)控制臺(tái)窗口 運(yùn)行結(jié)果如下:

|