Java Socket學習筆記

來源:互聯網
上載者:User

最近學了學Java Socket方面的東西,網上找了很多朋友的代碼參考了,做了兩個小例子,為資料使用。

一,網路編程中兩個主要的問題:

一個是如何準確的定位網路上一台或多台主機,另一個就是找到主機後如何可靠高效的進行資料轉送。
在TCP/IP協議中IP層主要負責網路主機的定位,資料轉送的路由,由IP地址可以唯一地確定Internet上的一台主機。
而TCP層則提供面嚮應用的可靠(tcp)的或非可靠(UDP)的資料轉送機制,這是網路編程的主要對象,一般不需要關心IP層是如何處理資料的。

目前較為流行的網路編程模型是客戶機/伺服器(C/S)結構。即通訊雙方一方作為伺服器等待客戶提出請求並予以響應。客戶則在需要服務時向伺服器提 出申請。伺服器一般作為守護進程始終運行,監聽網路連接埠,一旦有客戶請求,就會啟動一個服務進程來響應該客戶,同時自己繼續監聽服務連接埠,使後來的客戶也 能及時得到服務。

二,兩類傳輸協議:TCP;UDP:

TCP是Tranfer Control Protocol的 簡稱,是一種連線導向的保證可靠傳輸的協議。通過TCP協議傳輸,得到的是一個順序的無差錯的資料流。發送方和接收方的成對的兩個socket之間必須建 立串連,以便在TCP協議的基礎上進行通訊,當一個socket(通常都是server socket)等待建立串連時,另一個socket可以要求進行串連,一旦這兩個socket串連起來,它們就可以進行雙向資料轉送,雙方都可以進行發送 或接收操作。

UDP是User Datagram Protocol的簡稱,是一種不需連線的協議,每個資料報都是一個獨立的資訊,包括完整的源地址或目的地址,它在網路上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。

UDP:

1,每個資料報中都給出了完整的地址資訊,因此無需要建立發送方和接收方的串連。

2,UDP傳輸資料時是有大小限制的,每個被傳輸的資料報必須限定在64KB之內。

3,UDP是一個不可靠的協議,發送方所發送的資料報並不一定以相同的次序到達接收方

TCP:

1,連線導向的協議,在socket之間進行資料轉送之前必然要建立串連,所以在TCP中需要連線時間。

2,TCP傳輸資料大小限制,一旦串連建立起來,雙方的socket就可以按統一的格式傳輸大的資料。

3,TCP是一個可靠的協議,它確保接收方完全正確地擷取發送方所發送的全部資料。

瞭解Java Socket:

所謂socket通常也稱作"通訊端",用於描述IP地址和連接埠,是一個通訊鏈的控制代碼。應用程式通常通過"通訊端"向網路發出請求或者應答網路請求。

網路上的兩個程式通過一個雙向的通訊串連實現資料的交換,這個雙向鏈路的一端稱為一個Socket。Socket通常用來實現客戶方和服務方的串連。Socket是TCP/IP協議的一個十分流行的編程介面,一個Socket由一個IP地址和一個連接埠號碼唯一確定。

但是,Socket所支援的協議種類也不光TCP/IP一種,因此兩者之間是沒有必然聯絡的。在Java環境下,Socket編程主要是指基於TCP/IP協議的網路編程。

Socket通訊的過程:

Server端Listen(監聽)某個連接埠是否有串連請求,Client端向Server 端發出Connect(串連)請求,Server端向Client端發回Accept(接受)訊息。一個串連就建立起來了。Server端和Client 端都可以通過Send,Write等方法與對方通訊。

通常Socket通訊包括四個步驟:

1、建立Socket。

2、開啟串連到Socket的輸入/出流。

3、按照一定的協議對Socket進行讀/寫操作。

4、關閉Socket.(在實際應用中,並未使用到顯示的close,雖然很多文章都推薦如此,不過在我的程式中,可能因為程式本身比較簡單,要求不高,所以並未造成什麼影響。

下面做了兩個例子:一個是單線程的Socket通訊,二個是多線程的Socket通訊

單線程:

package com.zyujie.socket;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class ServerApp {public static void main(String[] args) throws IOException {//建立服務端,監聽連接埠6688,連接埠號碼是從0~65535之間的,socket的連接埠最好是1024以上。1024之前的連接埠已經被Tcp/Ip 作為保留連接埠ServerSocket server = new ServerSocket(6688);//接受到一個串連,並且返回一個用戶端的Socket對象執行個體Socket client = server.accept();//原始的位元組流來源於Socket的兩個方法.getInputStream()和getOutputStream()//這裡我們建立緩衝,把原始的位元組流轉變為UnicodeBufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));PrintWriter out = new PrintWriter(client.getOutputStream());while (true) {//一行一行的讀取用戶端訊息String str = in.readLine();System.out.println(str);//返回訊息給用戶端out.println("服務端已收到訊息...");out.flush();//伺服器端讀到end就結束Socket通訊,監聽退出if (str.equals("end")){break;}}//socket執行個體,串連關閉client.close();}}

 

package com.zyujie.socket;import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.InetAddress;import java.net.Socket;public class ClientApp {private static Socket server;public static void main(String[] args) throws Exception {//InetAddress是java.net包中的類,其靜態方法是得到本機IP和通過名字或IP直接得到InetAddress的方法server = new Socket(InetAddress.getLocalHost(), 6688);BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));PrintWriter out = new PrintWriter(server.getOutputStream());//控制台輸入字串BufferedReader wt = new BufferedReader(new InputStreamReader(System.in));while (true) {//一行一行的讀取控制台的輸入String str = wt.readLine();//發送給伺服器端out.println(str);out.flush();if (str.equals("end")) {break;}//讀取伺服器端返回的訊息System.out.println(in.readLine());}//socket執行個體,串連關閉server.close();}}

多線程的Socket通訊,只提供了服務端代碼,用戶端和單線程的一樣:

package com.zyujie.socket;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class SocketServer extends Thread {private Socket client;/* * 建構函式,接收每一個socket執行個體 */public SocketServer(Socket socket) {this.client = socket;}/* * 線程執行方法 */public void run() {try {//這裡我們建立輸入和輸出的緩衝,把原始的位元組流轉變為UnicodeBufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));PrintWriter out = new PrintWriter(client.getOutputStream());while (true) {//讀取用戶端訊息String str = in.readLine();System.out.println(str);//返回給用戶端訊息out.println("服務端已收到訊息...");out.flush();//遇到end就結束,這裡只是結束單個用戶端的串連if (str.equals("end")){break;}}//socket執行個體,串連關閉client.close();} catch (IOException ex) {} finally {}}/* * 啟用線程方法實現多個使用者串連socket伺服器端. */public static void main(String[] args) throws IOException {//建立服務端,監聽連接埠6688ServerSocket server = new ServerSocket(6688);//使用伺服器端保持永久監聽狀態while (true) {//接收每一個用戶端的串連,並返回socket執行個體SocketServer ss = new SocketServer(server.accept());//為每一個用戶端啟一個線程,去執行操作ss.start();}}}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.