Java Socket編程(二) Java面向連接的類
Java面向連接的類
Sockets有兩種主要的操作方式:面向連接的和無連接的.面向連接的sockets操作就像一部電話,他們必須建立一個(gè)連接和一人呼叫.所有的事情在到達(dá)時(shí)的順序與它們出發(fā)時(shí)的順序時(shí)一樣.無連接的sockets操作就像是一個(gè)郵件投遞,,沒有什么保證,多個(gè)郵件可能在到達(dá)時(shí)的順序與出發(fā)時(shí)的順序不一樣.
到底用哪種模式是郵應(yīng)用程序的需要決定的.如果可靠性更重要的話,用面向連接的操作會好一些.比如文件服務(wù)器需要他們的數(shù)據(jù)的正確性和有序性.如果一些數(shù)據(jù)丟失了,系統(tǒng)的有效性將會失去.一些服務(wù)器,比如間歇性地發(fā)送一些數(shù)據(jù)塊.如果數(shù)據(jù)丟了的話,服務(wù)器并不想要再重新發(fā)過一次.因?yàn)楫?dāng)數(shù)據(jù)到達(dá)的時(shí)候,它可能已經(jīng)過時(shí)了.確保數(shù)據(jù)的有序性和正確性需要額外的操作的內(nèi)存消耗,額外的費(fèi)用將會降低系統(tǒng)的回應(yīng)速率.
無連接的操作使用數(shù)據(jù)報(bào)協(xié)議.一個(gè)數(shù)據(jù)報(bào)是一個(gè)獨(dú)立的單元,它包含了所有的這次投遞的信息.把它想象成一個(gè)信封吧,它有目的地址和要發(fā)送的內(nèi)容.這個(gè)模式下的socket不需要連接一個(gè)目的的socket,它只是簡單地投出數(shù)據(jù)報(bào).無連接的操作是快速的和高效的,但是數(shù)據(jù)安全性不佳.
面向連接的操作使用TCP協(xié)議.一個(gè)這個(gè)模式下的socket必須在發(fā)送數(shù)據(jù)之前與目的地的socket取得一個(gè)連接.一旦連接建立了,sockets就可以使用一個(gè)流接口:打開-讀-寫-關(guān)閉.所有的發(fā)送的信息都會在另一端以同樣的順序被接收.面向連接的操作比無連接的操作效率更低,但是數(shù)據(jù)的安全性更高.
SUN一直是網(wǎng)絡(luò)建設(shè)的支持者,所以在Java中支持sockets就不足為奇了.實(shí)際上,Java降低了建立一個(gè)sockets程序的難度.每一個(gè)傳輸模式都被封裝到了不同的類中.面向連接的類將會首先被我們討論.
在Java中面向連接的類有兩種形式,它們分別是客戶端和服務(wù)器端.客戶端這一部分是最簡單的,所以我們先討論它.
列表9.1列出了一個(gè)簡單的客戶端的程序.它向一個(gè)服務(wù)器發(fā)出一個(gè)請求,取回一個(gè)HTML文檔,并把它顯示在控制臺上.
9.1一個(gè)簡單的socket客戶端
import java.io.*;
import java.net.*;
/**
* 一個(gè)簡單的從服務(wù)器取回一個(gè)HTML頁面的程序
* 注意:merlin是本地機(jī)器的名字
*/
public class SimpleWebClient {
public static void main(String args[])
{
try
{
// 打開一個(gè)客戶端socket連接
Socket clientSocket1 = new Socket("merlin", 80);
System.out.println("Client1: " + clientSocket1);
// 取得一個(gè)網(wǎng)頁
getPage(clientSocket1);
}
catch (UnknownHostException uhe)
{
System.out.println("UnknownHostException: " + uhe);
}
catch (IOException ioe)
{
System.err.println("IOException: " + ioe);
}
}
/**
*通過建立的連接請求一個(gè)頁面,顯示回應(yīng)然后關(guān)閉socket
*/
public static void getPage(Socket clientSocket)
{
try
{
// 需要輸入和輸出流
DataOutputStream outbound = new DataOutputStream(
clientSocket.getOutputStream() );
DataInputStream inbound = new DataInputStream(
clientSocket.getInputStream() );
// 向服務(wù)器發(fā)出HTTP請求
outbound.writeBytes("GET / HTTP/1.0\r\n\r\n");
// 讀出回應(yīng)
String responseLine;
while ((responseLine = inbound.readLine()) != null)
{
// 把每一行顯示出來
System.out.println(responseLine);
if ( responseLine.indexOf("") != -1 )
break;
}
// 清除
outbound.close();
inbound.close();
clientSocket.close();
}
catch (IOException ioe)
{
System.out.println("IOException: " + ioe);
}
}
}
回憶一個(gè),一個(gè)客戶端向一個(gè)正在監(jiān)聽的服務(wù)器socket發(fā)出一個(gè)連接.客戶端的sockets是用Socket類建立的.下面的程序建立了一個(gè)客戶端的socket并且連接到了一個(gè)主機(jī):
Socket clientSocket = new Socket("merlin", 80);
第一個(gè)參數(shù)是你想要連接的主機(jī)的名稱,第二個(gè)參數(shù)是端口號.一個(gè)主機(jī)名稱指定了目的的名稱.端口號指定了由哪個(gè)應(yīng)用程序來接收.在我們的情況下,必須指定80,因?yàn)樗悄J(rèn)的HTTP協(xié)議的端口.另外的知名的端口列在表9.1中,看:
知名的端品:
echo 7
daytime 13
daytime 13
ftp 21
telnet 23
smtp 25
finger 79
http 80
pop3 110
因?yàn)镾ocket類是面向連接的,它提供了一個(gè)可供讀寫的流接口.java.io包中的類可以用來訪問一個(gè)已連接的socket:
DataOutputStream outbound = new DataOutputStream(
clientSocket.getOutputStream() );
DataInputStream inbound = new DataInputStream( clientSocket.getInputStream()
);
一旦流建立了,一般的流操作就可以做了:
outbound.writeBytes("GET / HTTP/1.0\r\n\r\n);
String responseLine;
while ( (responseLine = inbound.readLine()) != null)
{
System.out.println(responseLine);
}
以上的小程序請求了一個(gè)WEB頁面并且把它顯示出來.當(dāng)程序完成之后,連接必須關(guān)閉.
outbound.close();
inbound.close();
clientSocket.close();
注意socket流必須首先關(guān)閉.所有的的socket流必須在socket關(guān)閉之前關(guān)閉.這個(gè)小程序非常地簡單,但是所有的客戶端程序都必須遵首下面的基本的步驟:
1.建立客戶端socket連接.
2.得到socket的讀和寫的流.
3.利用流.
4.關(guān)閉流.
5.關(guān)閉socket.
使用一個(gè)服務(wù)器端的socket只是有一點(diǎn)復(fù)雜,它將在下面講到.
- java網(wǎng)絡(luò)編程之socket網(wǎng)絡(luò)編程示例(服務(wù)器端/客戶端)
- java socket編程實(shí)例代碼講解
- 實(shí)現(xiàn)了基于TCP的Java Socket編程實(shí)例代碼
- Java基于Tcp協(xié)議的socket編程實(shí)例
- Java Socket編程(四) 重復(fù)和并發(fā)服務(wù)器
- Java Socket編程(一) Socket傳輸模式
- Java Socket編程(三) 服務(wù)器Sockets
- Java Socket編程(五) 簡單的WEB服務(wù)器
- Java網(wǎng)絡(luò)編程基礎(chǔ)教程之Socket入門實(shí)例
- Java基于socket編程相關(guān)知識解析
相關(guān)文章
關(guān)于springboot中的自定義配置項(xiàng)
這篇文章主要介紹了關(guān)于springboot中的自定義配置項(xiàng),在項(xiàng)目開發(fā)的過程中,經(jīng)常需要自定義系統(tǒng)業(yè)務(wù)方面的配置文件及配置項(xiàng),Spring Boot提供了@value注解、@ConfigurationProperties注解和Environment接口等3種方式自定義配置項(xiàng),需要的朋友可以參考下2023-07-07
Java基本數(shù)據(jù)類型(動力節(jié)點(diǎn)java學(xué)院整理)
Java數(shù)據(jù)類型(type)可以分為兩大類:基本類型(primitive types)和引用類型(reference types)。下面是動力節(jié)點(diǎn)給大家整理java基本數(shù)據(jù)類型相關(guān)知識,感興趣的朋友一起學(xué)習(xí)吧2017-03-03
javaweb實(shí)現(xiàn)百度GPS定位接口(經(jīng)緯度)
這篇文章主要介紹了javaweb實(shí)現(xiàn)百度GPS定位接口(經(jīng)緯度),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02

