標籤:三向交握 統一 位元組流 使用者數 相對 test 發送請求 關閉 基於
原文出自:http://www.cnblogs.com/rocomp/p/4790340.html
Socket是網路驅動層提供給API和一種機制。可以把Socket比喻成一個港口碼頭,應用程式只要把貨物放到港口碼頭上,就算完成了貨物的運送。對於接收方應用程式也要建立一個港口碼頭,只需等待貨物到達碼頭後將貨物取走。
InetAddress
InetAddress類用於標識網路上的硬體資源,標識互連網協議(IP)地址。
該類沒有構造方法
1 //擷取原生InetAddress執行個體2 InetAddress address =InetAddress.getLocalHost();3 address.getHostName();//擷取電腦名稱4 address.getHostAddress();//擷取IP地址5 byte[] bytes = address.getAddress();//擷取位元組數組形式的IP地址,以點分隔的四部分6 7 //擷取其他主機的InetAddress執行個體8 InetAddress address2 =InetAddress.getByName("其他主機名稱");9 InetAddress address3 =InetAddress.getByName("IP地址");
二、URL類
1、URL(Uniform Resource Locator)統一資源定位器,表示Internet上某一資源的地址,協議名:資源名稱
1 //建立一個URL的執行個體 2 URL baidu =new URL("http://www.baidu.com"); 3 URL url =new URL(baidu,"/index.html?username=tom#test");//?表示參數,#表示錨點 4 url.getProtocol();//擷取協議 5 url.getHost();//擷取主機 6 url.getPort();//如果沒有指定連接埠號碼,根據協議不同使用預設連接埠。此時getPort()方法的傳回值為 -1 7 url.getPath();//擷取檔案路徑 8 url.getFile();//檔案名稱,包括檔案路徑+參數 9 url.getRef();//相對路徑,就是錨點,即#號後面的內容10 url.getQuery();//查詢字串,即參數
2、使用URL讀取網頁內容
通過URL對象的openStream()方法可以得到指定資源的輸入資料流,通過流能夠讀取或訪問網頁上的資源
1 //使用URL讀取網頁內容 2 //建立一個URL執行個體 3 URL url =new URL("http://www.baidu.com"); 4 InputStream is = url.openStream();//通過openStream方法擷取資源的位元組輸入資料流 5 InputStreamReader isr =newInputStreamReader(is,"UTF-8");//將位元組輸入資料流轉換為字元輸入資料流,如果不指定編碼,中文可能會出現亂碼 6 BufferedReader br =newBufferedReader(isr);//為字元輸入資料流添加緩衝,提高讀取效率 7 String data = br.readLine();//讀取資料 8 while(data!=null){ 9 System.out.println(data);//輸出資料10 data = br.readerLine();11 }12 br.close();13 isr.colose();14 is.close();
三、TCP編程
1、TCP協議是連線導向的、可靠的、有序的、以位元組流的方式發送資料,通過三向交握方式建立串連,形成傳輸資料的通道,在串連中進行大量資料的傳輸,效率會稍低
2、Java中基於TCP協議實現網路通訊的類
用戶端的Socket類
伺服器端的ServerSocket類
3、Socket通訊的步驟
① 建立ServerSocket和Socket
② 開啟串連到Socket的輸入/輸出流
③ 按照協議對Socket進行讀/寫操作
④ 關閉輸入輸出資料流、關閉Socket
4、伺服器端:
① 建立ServerSocket對象,綁定監聽連接埠
② 通過accept()方法監聽用戶端請求
③ 串連建立後,通過輸入資料流讀取用戶端發送的請求資訊
④ 通過輸出資料流向用戶端發送鄉音資訊
⑤ 關閉相關資源
1 /** 2 * 基於TCP協議的Socket通訊,實現使用者登入,服務端 3 */ 4 //1、建立一個伺服器端Socket,即ServerSocket,指定綁定的連接埠,並監聽此連接埠 5 ServerSocket serverSocket =newServerSocket(10086);//1024-65535的某個連接埠 6 //2、調用accept()方法開始監聽,等待用戶端的串連 7 Socket socket = serverSocket.accept(); 8 //3、擷取輸入資料流,並讀取用戶端資訊 9 InputStream is = socket.getInputStream();10 InputStreamReader isr =newInputStreamReader(is);11 BufferedReader br =newBufferedReader(isr);12 String info =null;13 while((info=br.readLine())!=null){14 System.out.println("我是伺服器,用戶端說:"+info);15 }16 socket.shutdownInput();//關閉輸入資料流17 //4、擷取輸出資料流,響應用戶端的請求18 OutputStream os = socket.getOutputStream();19 PrintWriter pw = new PrintWriter(os);20 pw.write("歡迎您!");21 pw.flush();22 23 24 //5、關閉資源25 pw.close();26 os.close();27 br.close();28 isr.close();29 is.close();30 socket.close();31 serverSocket.close();
5、用戶端:
① 建立Socket對象,指明需要已連線的服務器的地址和連接埠號碼
② 串連建立後,通過輸出資料流想伺服器端發送請求資訊
③ 通過輸入資料流擷取伺服器響應的資訊
④ 關閉響應資源
1 //用戶端 2 //1、建立用戶端Socket,指定伺服器位址和連接埠 3 Socket socket =newSocket("localhost",10086); 4 //2、擷取輸出資料流,向伺服器端發送資訊 5 OutputStream os = socket.getOutputStream();//位元組輸出資料流 6 PrintWriter pw =newPrintWriter(os);//將輸出資料流封裝成列印流 7 pw.write("使用者名稱:admin;密碼:123"); 8 pw.flush(); 9 socket.shutdownOutput();10 //3、擷取輸入資料流,並讀取伺服器端的響應資訊11 InputStream is = socket.getInputStream();12 BufferedReader br = new BufferedReader(new InputStreamReader(is));13 String info = null;14 while((info=br.readLine())!null){15 System.out.println("我是用戶端,伺服器說:"+info);16 }17 18 //4、關閉資源19 br.close();20 is.close();21 pw.close();22 os.close();23 socket.close();
6、應用多線程實現伺服器與多用戶端之間的通訊
① 伺服器端建立ServerSocket,迴圈調用accept()等待用戶端串連
② 用戶端建立一個socket並請求和伺服器端串連
③ 伺服器端接受苦讀段請求,建立socket與該客戶建立專線串連
④ 建立串連的兩個socket在一個單獨的線程上對話
⑤ 伺服器端繼續等待新的串連
1 //伺服器線程處理 2 //和本線程相關的socket 3 Socket socket =null; 4 // 5 public serverThread(Socket socket){ 6 this.socket = socket; 7 } 8 9 publicvoid run(){10 //伺服器處理代碼11 }12 13 //============================================14 //伺服器代碼15 ServerSocket serverSocket =newServerSocket(10086);16 Socket socket =null;17 int count =0;//記錄用戶端的數量18 while(true){19 socket = serverScoket.accept();20 ServerThread serverThread =newServerThread(socket);21 serverThread.start();22 count++;23 System.out.println("用戶端串連的數量:"+count);24 }
四、UDP編程
UDP協議(使用者資料包通訊協定)是不需連線的、不可靠的、無序的,速度快
進行資料轉送時,首先將要傳輸的資料定義成資料報(Datagram),大小限制在64k,在資料報中指明資料索要達到的Socket(主機地址和連接埠號碼),然後再將資料報發送出去
DatagramPacket類:表示資料報包
DatagramSocket類:進行端到端通訊的類
1、伺服器端實現步驟
① 建立DatagramSocket,指定連接埠號碼
② 建立DatagramPacket
③ 接受用戶端發送的資料資訊
④ 讀取資料
1 //伺服器端,實現基於UDP的使用者登入 2 //1、建立伺服器端DatagramSocket,指定連接埠 3 DatagramSocket socket =new datagramSocket(10010); 4 //2、建立資料報,用於接受用戶端發送的資料 5 byte[] data =newbyte[1024];// 6 DatagramPacket packet =newDatagramPacket(data,data.length); 7 //3、接受用戶端發送的資料 8 socket.receive(packet);//此方法在接受資料報之前會一致阻塞 9 //4、讀取資料10 String info =newString(data,o,data.length);11 System.out.println("我是伺服器,用戶端告訴我"+info);12 13 14 //=========================================================15 //向用戶端響應資料16 //1、定義用戶端的地址、連接埠號碼、資料17 InetAddress address = packet.getAddress();18 int port = packet.getPort();19 byte[] data2 = "歡迎您!".geyBytes();20 //2、建立資料報,包含響應的資料資訊21 DatagramPacket packet2 = new DatagramPacket(data2,data2.length,address,port);22 //3、響應用戶端23 socket.send(packet2);24 //4、關閉資源25 socket.close();
2、用戶端實現步驟
① 定義發送資訊
② 建立DatagramPacket,包含將要發送的資訊
③ 建立DatagramSocket
④ 發送資料
1 //用戶端 2 //1、定義伺服器的地址、連接埠號碼、資料 3 InetAddress address =InetAddress.getByName("localhost"); 4 int port =10010; 5 byte[] data ="使用者名稱:admin;密碼:123".getBytes(); 6 //2、建立資料報,包含發送的資料資訊 7 DatagramPacket packet = newDatagramPacket(data,data,length,address,port); 8 //3、建立DatagramSocket對象 9 DatagramSocket socket =newDatagramSocket();10 //4、向伺服器發送資料11 socket.send(packet);12 13 14 //接受伺服器端響應資料15 //======================================16 //1、建立資料報,用於接受伺服器端響應資料17 byte[] data2 = new byte[1024];18 DatagramPacket packet2 = new DatagramPacket(data2,data2.length);19 //2、接受伺服器響應的資料20 socket.receive(packet2);21 String raply = new String(data2,0,packet2.getLenth());22 System.out.println("我是用戶端,伺服器說:"+reply);23 //4、關閉資源24 socket.close();
五、注意問題:
1、
多線程的優先順序問題:
根據實際的經驗,
適當的降低優先順序,否側可能會有程式運行效率低的情況
2、是否關閉輸出資料流和輸入資料流:
對於同一個socket,如果關閉了輸出資料流,則與該輸出資料流關聯的socket也會被關閉,所以一般不用關閉流,直接關閉socket即可
3、使用TCP通訊傳輸對象,IO中序列化部分
4、socket編程傳遞檔案,IO流部分
(轉)Java Socket編程