Java學習第十八節之網絡編程
一、 網絡基本概念
1、網絡通信協議:即是一種通信規範
2、網絡通信接口:包括硬件裝置和軟件設置,其中硬件設置是指實現結點之間的信息發送,軟件設置是指規定雙方進行通信的約定協議。
3、網絡概述——OSI模型(Open SystemInterconnection,開放式系統互聯)
注意:OSI的網絡層(即常用的就是包括IP的層)同時支持面向連接和無連接的通信,但是傳輸層只支持面向連接的通信;TCP/IP五層模型即把上邊的高三層統歸爲應用層,它的網絡層只提供無連接服務,但是傳輸層上同時提供兩種通信模式
4、IP地址,即是用來表示一臺計算機的身份證,由網絡地址(確定網絡)和主機地址(網絡中的主機)組成。
IP 地址的分爲A類、B類、C類(常用)、D類和E類,也可分爲IPV4和IPV6,目前使用的是IPV4,即4位十進制數,32位二進制數。
子網掩碼是爲了區分網絡地址和主機地址
5、傳輸協議分爲TCP和UDP
TCP(TransmissionControl Protocol 傳輸控制協議),使用三次握手的方式,可確保數據傳送的次序和傳輸的可靠性,先建立連接,再傳輸數據,最後釋放連接。在IP報文的協議號是6。
UDP(UserDatagram Protocol 用戶數據報協議),是一個無連接協議,傳輸數據之前和終端不建立連接,是不可靠的協議。在IP報文的協議號是17。
TCP與UDP的區別
① TCP協議面向連接,UDP協議面向非連接
② TCP協議傳輸速度慢,UDP協議傳輸速度快
③ TCP有丟包重傳機制,UDP沒有
④ TCP協議保證數據正確性,UDP協議可能丟包
6、TCP套接字Socket,Socket是用於機器之間的通信的類,還可對IP地址和端口進行描述
二、Socket編程,即就是網絡編程
1、類Socket的介紹
在java中套接字Socket(通信接口)被抽象爲類,我們只需要創建Socket對象就可以使用套接字。Socket可以看做兩個程序進行通訊連接的一個端點,Socket類中有輸入、輸出對象,同時能實現服務器之間的數據傳輸
常用方法:
●public InetAddressgetInetAddress(); //返回此套接字的地址
●public InetAddressgetLocalAddress(); //獲得套接字綁定的本地地址
●public int port(); //獲得此套接字連接到的遠程端口
2、類ServerSocket的介紹
ServerSocket類:在客戶端使用的是ServerSocket,只要是用於接收客戶端傳來的對象
常用構造函數:
● ServerSocket(); //創建非綁定服務器套接字
● ServerSocket(int port); //創建綁定到特定端口的服務器的套接字
● ServerSocket(int port,intbacklog);
//利用指定的backlog創建服務器套接字,並將其綁定到指定的本地端口號
● ServerSocket(int port,int backlog,InetAddress bindAddr);
//使用指定的端口、偵聽backlog和要綁定到的本地IP地址創建服務器
提供的主要方法:
● public Socket accept();//偵聽並接收到連接此套接字的連接,此方法在進行連接之前一直阻塞
● public void bind(SocketAddress addr);
//返回此服務器套接字的地址,IP地址和端口號都被封裝在addr中
● public void close(); //關閉服務器套接字
● public InetAddress getInetAddress(); //返回此服務器套接字的本地地址
● public int getLocalPort(); //返回套接字進行偵聽的端口
● public void setSoTimeout(int timeout); //啓動帶有指定超時值的SO_TIMEOUT,以ms爲單位
3、代碼應用
部分代碼解讀:
Socket服務器:(注意多個客戶端訪問時要用多線程解決出現的問題)
① ServerSocket server=new ServerSocket(port);//創建一個端口
② Sockets=server.accept(); //只有當客戶端請求並連接,函數纔會返回
③ BufferedReader br=newBufferedReader((new InputStream(s.getInputStream()));//接收數據
④ PrintWriter pw=newPrintWriter(new OutputStreamWriter(s.getOutputStream()),true)//發送數據
注意:PrintWriter會自動緩衝,使用它的時候需要使用println()函數
Socket客戶端:
① Socket socket=new Socket(host,port); //打開一個套接字,發送請求
② BufferedReader br=newBufferedReader((new InputStream(s.getInputStream()));//接收數據
③ PrintWriter pw=newPrintWriter(new OutputStreamWriter(s.getOutputStream()),true)//發送數據
注意:以上代碼均屬於C/S,需要同時維護客戶端和服務器的代碼
B/S的瀏覽器和服務器只需要維護一方即可
代碼出現問題一、在套接字中會發生阻塞的地方
A、實例化Socket對象的時候會阻塞
解決方案:Socket socket=newSocket(); //創建無連接Socket對象
socket.connect(new InetSocketAddress(host, port),timeout); //設置超時
B、在in.nextLine()類似操作時會阻塞
解決方案:設置socket.setSoTimeout(long); //設置超時時間
代碼出現問題二、
A. 當客戶端想要關閉套接字的時候,但卻不能確定服務器是否還在發送數據,但是隻要一關閉就立刻斷掉
解決方案:socket.shutdownInput(); //關閉輸入流
Socket.shutdownOutput(); //關閉輸出流
4、DatagramPacket介紹
作爲接受方法中的參數,DatagramPacket的數組,一個空的數組用來存放、接收數據對象中的數組
作爲發送方法中的參數,DatagramPacket本身包含了目的端的IP和端口,以及存儲例如要發送的內容的指定了長度的字節型數組