1. 程式人生 > >java網路程式設計:8、基於TCP的socket程式設計(一)簡單的socket通訊_一個客戶端

java網路程式設計:8、基於TCP的socket程式設計(一)簡單的socket通訊_一個客戶端

宣告:本教程不收取任何費用,歡迎轉載,尊重作者勞動成果,不得用於商業用途,侵權必究!!!

文章目錄

一、基於tcp的程式設計,就好像用電話進行交談一樣

二、在java中用於程式設計網路程式的類

三、套接字 + (輸出、輸入流)

1、伺服器程式編寫基本步驟:

2、客戶端程式編寫基本步驟:

四、程式碼編寫

1、伺服器端程式的編寫

2、客戶端程式的編寫

3、列印輸出

4、你這個sever和client都是在同一個程式當中編寫的,

那麼我如何在兩臺機器之間進行通訊呢?

五、系列文章(java網路程式設計)


一、基於tcp的程式設計,就好像用電話進行交談一樣

基於tcp的程式設計,就好像用電話進行交談一樣,我們總是一個人在等待電話,另一個人去撥打電話,要想能夠打通這個電話,在你撥電話號碼的時候,這個人一定是已經在等待電話了,隨時可以接電話。如果這個人不在電話旁邊,你就無法完成這次通訊,也就是說通訊雙方是不對等的。

等待接電話的一方,我們把它叫做伺服器端,撥電話號碼的這一方,我們把它叫做客戶端。也就是在網路中等待連線請求到來的一方,為伺服器端,發起連線請求的一方為客戶端

要進行通訊,首先我們要建立套接字,套接字實際上是一個抽象的概念,在套接字程式設計模型中,套接字是作為通訊鏈路的端點。我們可以把套接字看成是電話機,有了套接字才有了通訊的工具,我們可以把ip地址看成是電話號碼,埠號看成是分機號。

 

二、在java中用於程式設計網路程式的類

在java中用於程式設計網路程式的類,是通過java.net這個包給我們提供的。裡面的ServerSocket類是用來建立伺服器端的套接字,Socket類用來建立客戶端的套接字

對於伺服器端來說,我們去呼叫ServerSocket(int port)這個構造方法,然後去建立一個伺服器端的套接字,繫結到指定的埠上,然後去呼叫accept方法,這個方法它等待客戶請求到來,然後返回一個套接字,用這個套接字去和我們的客戶端進行通訊,對於伺服器端套接字來說,它不能直接用於資料的交換,我們可以把這個伺服器端的套接字看成是一個監聽套接字,它負責監聽客戶端請求,一旦有客戶端請求到來,那麼這個accept方法就接收客戶端請求,然後返回一個用於資料通訊的套接字。

對於客戶端來說,我可以呼叫Socket的構造方法Socket(InetAddress address,int port),然後指定ip地址、指定埠號,那麼就可以建立一個到我們伺服器端,指定埠的一個程序的連線。在java當中,ip地址是用InetAddress這個類來表示的,在這個類當中提供了很多有用的方法。

如:getByName(String host)靜態方法,可通過主機名來獲得對應的ip地址。

如果我們傳遞的本身就是ip地址的字串格式,那麼它會將我們的ip地址直接返回。

getLocalHost()靜態方法,可返回我們本地的ip地址 

 

三、套接字 + (輸出、輸入流)

接下來對於伺服器端和客戶端,那麼我們就可以利用Socket裡面的getOutputStream方法去獲取一個輸出流,用於傳送資料,getInputStream方法去獲取一個輸入流,用於從網路上讀取資料。同樣的再客戶端也可以這樣獲取輸出流、輸入流。

1、伺服器程式編寫基本步驟:

①呼叫ServerSocket(int port)建立一個伺服器端套接字,並繫結到指定埠上;②呼叫accept(),監聽連線請求,如果客戶端請求連線,則接受連線,返回通訊套接字。③呼叫Socket類的getOutputStream()和getInputStream獲取輸出流和輸入流,開始網路資料的傳送和接收。④最後關閉通訊套接字。

2、客戶端程式編寫基本步驟:

①呼叫Socket()建立一個流套接字,並連線到伺服器端;②呼叫Socket類的getOutputStream()和getInputStream獲取輸出流和輸入流,開始網路資料的傳送和接收。③最後關閉通訊套接字。

 

四、程式碼編寫

基於TCP的socket程式設計_簡單的socket通訊_一個客戶端

1、伺服器端程式的編寫

/**
	 * 伺服器端程式的編寫
	 */
	public static void server() {
		try {
			// 建立伺服器端套接字,繫結到6000的埠上
			ServerSocket ss = new ServerSocket(6000);
			// 呼叫accept方法就會阻塞,直到客戶端有連線請求到來的時候。
			// 它會返回一個套接字,然後就可以利用這個套接字與客戶端進行資料通訊。
			Socket s = ss.accept();
			// 可以利用套接字獲取輸出流、輸入流
			OutputStream os = s.getOutputStream();
			InputStream is = s.getInputStream();
			// 利用輸出流向客戶端傳送資料
			// getBytes將字串轉換成位元組陣列
			os.write("Hello,welcome you,client!".getBytes());
			// 利用輸入流從網路上讀取資料
			// 建立位元組陣列
			byte[] buf = new byte[100];
			// 將資料讀取到buf位元組陣列當中,它會返回實際讀取的位元組數
			int len = is.read(buf);
			// 將我們讀取的資料打印出來
			System.out.println(new String(buf, 0, len));
			// 完成通訊之後,我們可以將輸出流、輸入流、套接字、伺服器端的套接字都關閉
			os.close();
			is.close();
			s.close();
			ss.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

2、客戶端程式的編寫

/**
	 * 客戶端程式的編寫
	 */
	public static void client() {
		try {
			// 建立一個客戶端的套接字,指定一個ip地址和埠。
			// 讓它連線到我們伺服器端上,在這個埠上等待連線的伺服器程序
			// ip地址:你可以指定主機名,或者指定ip地址,讓它直接返回。
			// 我們在編寫程式的時候,可能沒有兩臺機器,沒有關係,我們可以在一臺機器上,
			// 讓我們服務端程式和客戶端程式,通過網路進行通訊。
			// 那麼我們可以獲取本地的ip地址,它有三種方式:
			// InetAddress.getByName("localhost")
			// InetAddress.getByName("127.0.0.1")//是我們本地的迴路地址
			// InetAddress.getByName(null)//它也可以返回本地的IP地址
			//那麼這三種方式,即使這我們的機器上沒有網絡卡,也沒有關係。
			//那麼作為一臺pc機,它都會有一個"127.0.0.1"作為本地的一個迴路地址,那麼我們用這個地址,
			//就可以測試我們的網路程式。 
			//注:你在客戶端傳送連線請求的埠號,和伺服器端等待連線的埠號一定要一致。
			//這就好像你打電話一樣,那麼我的分機號是6000,那麼你打過來的時候你轉這個分機號,你也要轉6000
			//才能夠和我進行通訊,你不能說你隨便轉個分機號,你想轉5000和我進行通訊,那是不可能的。
			Socket s = new Socket(InetAddress.getByName("localhost"), 6000);
			// 可以利用套接字獲取輸出流、輸入流
			OutputStream os = s.getOutputStream();
			InputStream is = s.getInputStream();
			//輸入流向伺服器端讀取資料
			byte[] buf = new byte[100];
			int len = is.read(buf);
			System.out.println(new String(buf, 0, len));
			//輸出流向伺服器端傳送資料
			os.write("Hello,this is zhangsan".getBytes());
			//完成通訊之後,我們可以將輸出流、輸入流、套接字都關閉
			os.close();
			is.close();
			s.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}

	}

3、列印輸出

開啟兩個Console

啟動伺服器端

啟動客戶端後,進行通訊,如下圖:

我們這個伺服器程式只為一個客戶進行了服務,當它為這個客戶服務完成之後,那麼它就退出了!

通常我們在開發一個伺服器端程式的時候,那麼我們是要為多個客戶同時提供服務。

下面我們就採用多執行緒的技術來改造一下,我們的伺服器端程式。

詳見下篇文章:java網路程式設計:9、基於TCP的socket程式設計(二)迴圈監聽接收多個客戶端_多執行緒伺服器程式

 

4、你這個sever和client都是在同一個程式當中編寫的,

那麼我如何在兩臺機器之間進行通訊呢?

// 你這個sever和client都是在同一個程式當中編寫的,那麼我如何在兩臺機器之間進行通訊呢?

// 程式和程序是不同的概念,我們雖然在一個程式當中寫了一個server和一個client,

// 但是我們在進行網路通訊的的時候,是一個程序和另一個程序在進行通訊,那麼當我們執行server的時候,

// 它呼叫的是server這個方法,那麼啟動了一個程序,這個程序我們可以把它看作是伺服器端程序,當我們呼叫

// client方法的時候,那麼也啟動了一個程序,我們可以把它看成是客戶端程序。那麼由這個伺服器端程序和客戶端

// 程序在進行通訊。你要把這個程式放到兩個機器上進行通訊,很簡單每一個機器上你拷貝一份程式碼就可以了。

// 伺服器端執行sever方法,客戶端執行client方法就可以了。

// 所以要理解我們在通訊的時候,真正通訊的是我們的程序。

 

五、系列文章(java網路程式設計)

 

 java網路程式設計:1、計算機網路?網路通訊的組成?什麼是ip、協議、埠號?

 java網路程式設計:2、IP地址、協議、網路狀況、網路異質性問題的解決

 java網路程式設計:3、ISO/OSI七層參考模型

 java網路程式設計:4、OSI各層所使用的協議

 java網路程式設計:5、資料封裝

 java網路程式設計:6、TCP/IP模型、TCP/IP模型與OSI參考模型的對應關係

 java網路程式設計:7、埠、套接字(socket)的引入

 java網路程式設計:8、基於TCP的socket程式設計(一)簡單的socket通訊_一個客戶端

 java網路程式設計:9、基於TCP的socket程式設計(二)伺服器端迴圈監聽接收多個客戶端_多執行緒伺服器程式

 java網路程式設計:10、基於TCP的socket程式設計(三)緩衝流、flush方法、關閉流

 java網路程式設計:11、基於UDP的socket程式設計(一)理論、基本步驟

 java網路程式設計:12、基於UDP的socket程式設計(二)程式碼通訊-簡單例項

 java網路程式設計:13、基於UDP的socket程式設計(三)實現相互發送接收訊息