1 Socket概述
(1)在計(jì)算機(jī)網(wǎng)絡(luò)編程技術(shù)中,兩個(gè)進(jìn)程或者說兩臺(tái)計(jì)算機(jī)可以通過一個(gè)網(wǎng)絡(luò)通信連接實(shí)現(xiàn)數(shù)據(jù)的交換,這種通信鏈路的端點(diǎn)就被稱為“套接字”(Socket)。
(2)Socket是網(wǎng)絡(luò)驅(qū)動(dòng)層提供給應(yīng)用程序的一個(gè)接口或者說一種機(jī)制。
(3)使用物流送快遞的例子來說明Socket:
????????-->發(fā)件人將有收貨人地址信息的貨物送到快遞站,發(fā)件人不用關(guān)心物流是如何進(jìn)行的,貨物被送到收貨人所在地區(qū)的快遞站點(diǎn),進(jìn)行配送,收貨人等待收貨就可以了。
????????-->這個(gè)過程很形象地說明了信息在網(wǎng)絡(luò)中傳遞的過程。其中,貨物就是數(shù)據(jù)信息,2個(gè)快遞站點(diǎn)就是2個(gè)端點(diǎn)Socket。
2 java.net包
(1)java.net包提供了若干支持基于套接字的客戶端/服務(wù)器通信的類。
(2)java.net包中常用的類有Socket、ServerSocket、DatagramPacket、DatagramSocket、InetAddress、URL、URLConnection和URLEncoder等。
(2)為了監(jiān)聽客戶端的連接請(qǐng)求,可以使用ServerSocket類。
(3)Socket類實(shí)現(xiàn)用于網(wǎng)絡(luò)上進(jìn)程間通信的套接字。
(4)DatagramSocket類使用UDP協(xié)議實(shí)現(xiàn)客戶端和服務(wù)器套接字。
(5)DatagramPacket類使用DatagramSocket類的對(duì)象封裝設(shè)置和收到的數(shù)據(jù)報(bào)。
(6)InetAddress類表示Internet地址。
(7)在創(chuàng)建數(shù)據(jù)報(bào)報(bào)文和Socket對(duì)象時(shí),可以使用InetAddress類。
3 基于TCP協(xié)議的Socket編程
3.1 Socket類和ServerSocket類
(1)java.net包的兩個(gè)類Socket和ServerSocket,分別用來實(shí)現(xiàn)雙向安全連接的客戶端和服務(wù)器端,它們是基于TCP協(xié)議進(jìn)行工作的,工作過程如同打電話的過程,只有雙方都接通了,才能開始通話。
(2)進(jìn)行網(wǎng)絡(luò)通信時(shí),Socket需要借助數(shù)據(jù)流來完成數(shù)據(jù)的傳遞工作。
(3)一個(gè)應(yīng)用程序要通過網(wǎng)絡(luò)向另一個(gè)應(yīng)用程序發(fā)送數(shù)據(jù),只要簡單地創(chuàng)建Socket,然后將數(shù)據(jù)寫入到與該Socket關(guān)聯(lián)的輸出流即可。對(duì)應(yīng)的,接收方的應(yīng)用程序創(chuàng)建Socket,從相關(guān)聯(lián)的輸入流讀取數(shù)據(jù)即可。
(4)注意:2個(gè)端點(diǎn)在基于TCP協(xié)議的Socket編程中,經(jīng)常一個(gè)作為客戶端,一個(gè)作為服務(wù)器端,也就是遵循client-server模型。
3.1.1 Socket類
Socket對(duì)象在客戶端和服務(wù)器之間建立連接??捎肧ocket類的構(gòu)造方法創(chuàng)建套接字,并將此套接字連接至指定的主機(jī)和端口。
1)構(gòu)造方法
以主機(jī)名和端口號(hào)作為參數(shù)來創(chuàng)建一個(gè)Socket對(duì)象。創(chuàng)建對(duì)象時(shí)可能拋出UnknownHostException或IOException異常,必須捕獲它們。
Socket s = new Socket(hostName,port);
以InetAddress對(duì)象和端口號(hào)作為參數(shù)來創(chuàng)建一個(gè)Socket對(duì)象。構(gòu)造方法可能拋出IOException或UnknownHostException異常,必須捕獲并處理它們。
Socket s = new Socket(address,port);
2)常用方法
InetAddress getInetAddress();????? 返回與Socket對(duì)象關(guān)聯(lián)的InetAddress對(duì)象
int getPort();?????????????????????????????????? 返回此Socket對(duì)象的遠(yuǎn)程端口
int getLocalPort();?????????????????????????? 返回此Socket對(duì)象的本地端口
InputStream getInputStream();?????? 返回與此Socket對(duì)象相關(guān)聯(lián)的輸入流
OutputStream getOutputStream();? 返回與此Socket對(duì)象相關(guān)聯(lián)的輸出流
void? close();???????????????????????????????????? 關(guān)閉Socket
3.1.2 ServerSocket類
ServerSocket對(duì)象用于等待客戶端建立連接,連接建立后進(jìn)行通信。
1)構(gòu)造方法
ServerSocket ss = new ServerSocket(port);以端口號(hào)作為參數(shù),此端口號(hào)和Socket對(duì)象的端口號(hào)相對(duì)應(yīng)。
ServerSocket ss = new ServerSocket(port,maxqu);以端口號(hào)和最大隊(duì)列長度最為參數(shù),隊(duì)列長度表示系統(tǒng)在拒絕連接前可以擁有的客戶端連接數(shù)。
2)常用方法
Socket accept();用于等待客戶端發(fā)起通信,返回值是Socket對(duì)象。起到監(jiān)聽的作用,一旦監(jiān)聽到,則與客戶端建立連接進(jìn)行數(shù)據(jù)傳輸。
3.2 使用Socket編程實(shí)現(xiàn)登錄
3.2.1 實(shí)現(xiàn)單客戶端通信
Socket網(wǎng)絡(luò)編程一般分為以下4個(gè)步驟:
(1)建立連接。
(2)打開Socket關(guān)聯(lián)的輸入/輸出流。
(3)從數(shù)據(jù)流中寫入信息和讀取信息。
(4)關(guān)閉所有的數(shù)據(jù)流和Socket。
客戶端:
1)建立連接,連接指定服務(wù)器及端口;
2)打開與Socket對(duì)象關(guān)聯(lián)的輸出流;
3)向輸出流中寫入數(shù)據(jù);
4)打開與Socket對(duì)象關(guān)聯(lián)的輸入流;
5) 讀取指定服務(wù)器的響應(yīng)信息;
6)關(guān)閉所有數(shù)據(jù)流和Socket。
服務(wù)器端:
1)建立連接;
2)使用accept()方法監(jiān)聽等待客戶端發(fā)起通信;
3)打開Socket關(guān)聯(lián)的輸入流;
4)讀取客戶端發(fā)來的數(shù)據(jù);
5)打開Socket關(guān)聯(lián)的輸出流;
6)向輸出流中寫入響應(yīng)信息;
7)關(guān)閉所有數(shù)據(jù)流、Socket和ServerSocket;
3.2.2 實(shí)現(xiàn)多客戶端通信
一個(gè)服務(wù)器通常情況下都是面向很多的客戶端同時(shí)提供服務(wù),采用多線程的方式即可實(shí)現(xiàn)這一需求。在服務(wù)器端只做兩件事:負(fù)責(zé)監(jiān)聽,負(fù)責(zé)響應(yīng)。
客戶端的實(shí)現(xiàn)步驟不變。
服務(wù)器端的實(shí)現(xiàn)步驟:
1)創(chuàng)建服務(wù)器線程類,run()方法中實(shí)現(xiàn)對(duì)一個(gè)客戶端的請(qǐng)求的響應(yīng)處理;
2)創(chuàng)建服務(wù)器類,修改服務(wù)器端代碼,讓服務(wù)器端一直處于監(jiān)聽狀態(tài);
3)服務(wù)器端每監(jiān)聽到一個(gè)請(qǐng)求,創(chuàng)建一個(gè)線程對(duì)象并啟動(dòng);文章來源:http://www.zghlxwxcb.cn/news/detail-608958.html
部分代碼參考: 文章來源地址http://www.zghlxwxcb.cn/news/detail-608958.html
//多個(gè)客戶端向服務(wù)器發(fā)送信息,可以使用多線程,此時(shí),服務(wù)器只需要負(fù)責(zé)偵聽,偵聽到哪個(gè)客戶端,就執(zhí)行哪個(gè)客戶端線程
//這個(gè)客戶端線程里需要寫服務(wù)器端接收信息和發(fā)送響應(yīng)信息的代碼
public class ServerThread extends Thread {
Socket socket = null;// 初始化socket
// ServerThread線程的有參構(gòu)造方法需要傳遞一個(gè)Socket類型的參數(shù)
public ServerThread(Socket socket) {
this.socket = socket;
}
// run()方法里寫服務(wù)器端的響應(yīng)
@Override
public void run() {
InputStream is = null;
ObjectInputStream ois = null;
OutputStream os = null;
try {
// 打開輸入流
is = socket.getInputStream();
// 反序列化
ois = new ObjectInputStream(is);
// 讀取用戶信息
Object object = ois.readObject();
User user = (User) object;
System.out.println("用戶名:" + user.getUserName() + ",密碼:"
+ user.getPassword());
// 向客戶端發(fā)送響應(yīng)信息
os = socket.getOutputStream();
String str = "歡迎你,登陸成功";
byte[] bytes = str.getBytes();
os.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
os.close();
ois.close();
is.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//服務(wù)器端只需要負(fù)責(zé)偵聽客戶端
public static void main(String[] args) {
ServerSocket serverSocket=null;
try {
//創(chuàng)建ServerSocket對(duì)象
serverSocket=new ServerSocket(9000);
//服務(wù)器一直偵聽
while(true){
Socket socket=serverSocket.accept();
ServerThread st=new ServerThread(socket);
st.start();//偵聽到客戶端就啟動(dòng)線程
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
到了這里,關(guān)于【Java高級(jí)特性】Socket的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!