---------------------- android培訓、java培訓、期待與您交流! ----------------------
網絡編程概述
網絡傳輸基本三要素:
1、IP地址:找到對方IP。
2、端口號:數據要發送到對方指定的應用程序上,爲了標識這些應用程序。所以給這些網絡應用程序都用數字進行標識。爲了方便稱呼這個數字,叫做端口。邏輯端口。
3、傳輸協議:定義通信規則。這個通信規則稱爲協議。國際組織定義了通用協議TCP/IP。
網絡模型:
OSI參考模型 |
|
TCP/IP參考模型 |
應用層 |
|
應用層 |
表示層 |
||
會話層 |
||
傳輸層 |
|
傳輸層 |
網絡層 |
|
網際層 |
數據鏈路層 |
|
主機至網絡層 |
物理層 |
網絡通訊要素
IP地址:InetAddress
網絡中設備的標識。
不易記憶,可用主機名。
本地迴環地址:127.0.0.1,主機名:localhost。
互聯網協議IP:Internet Protocol;
端口號
用於標識進程的邏輯地址,不同進程的標識。
有效端口:0~65535,其中0~1024系統使用或保留端口。
傳輸協議
通訊的規則
常見協議:TCP,UDP。
TCP和UDP
UDP
用戶數據報協議(User Datagram Protocol);
將數據及源和目的封裝成數據包中,不需要建立連接。
每個數據報的大小在限制在64k內。
因面向無連接,是不可靠協議。
不需要建立連接,速度快。
聊天工具,視頻會議,桌面共享等,對數據實時性要求較高。
TCP
傳輸控制協議(Transmission Control Protocol)
面向連接。需建立連接,形成傳輸數據的通道。
在連接中進行大數據量傳輸。
通過三次握手完成連接,是可靠協議。
必須建立連接,效率會稍低。
Socket
Socket就是爲網絡服務提供的一種機制。
通信的兩端都有Socket。
網絡通信其實就是Socket間的通信。
數據在兩個Socket間通過IO傳輸。
傳輸
DatagramSocket與DatagramPacket。
建立發送端,接收端。
建立數據包。
調用Socket的發送接收方法。
關閉Socket。
發送端與接收端是兩個獨立的運行程序。
發送端:在發送端,要在數據包對象中明確目的地IP及端口。
class UdpSend { public static void main(String[] args) throws Exception { //1、創建UDP服務,通過DatagramSocket對象。 DatagramSocket ds = new DatagramSocket(); //2、確定數據,並封裝成數據包。DatagramPacket(byte[],int length,InetAddress address,int port) byte[] buf = "udp ge men lai la".getBytes(); DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000); //3、通過socket服務,將已有的數據包發送出去,通過send方法。 ds.send(dp); //4、關閉資源。 ds.close(); } } |
接收端:在接收端,要指定監聽的端口。
定義UDP的接收端。[day23-09]
思路:
1、定義udpsocket服務。通常都會監聽一個端口,其實就是給這個接收網絡應用程序定義數字標識。
爲了方便於明確哪些數據過來該應用程序可以處理。
2、定義一個數據包,因爲要存儲接收到的字節數據。
因爲數據包對象中有更多功能可以提取字節數據中的不同數據信息。
3、通過socket服務的receive方法將收到的數據存入已定義好的數據包中。
4、通過數據包對象的特有功能,將這些不同的數據取出,打印在控制檯上。
5、關閉資源。
class UdpRece { public static void main(String[] args) throws Exception { //1、創建UDP socket服務建立端點 DatagramSocket ds = new DatagramSocket(10000);
while (true) {
//2、定義數據包,用於存儲數據。 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3、通過服務的receive方法將收到的數據存入數據包中。 ds.receive(dp);//阻塞式方法。while(true)
//4、通過數據包的方法,獲取其中的數據。 String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+"::"+data+"::"+port); }
//5、關閉資源。 //ds.close(); } } |
TCP傳輸
1、TCP分客戶端和服務端
2、客戶端對應的對象是Socket。服務端對應的對象是ServerSocket
Socket和ServerSocket。
建立客戶端和服務器端。
建立連接後,通過Socket中的IO流進行數據的傳輸。
關閉socket
同樣,客戶端與服務器端是兩個獨立的應用程序。
基本思路(客戶端)
客戶端
通過查閱Socket對象,發現該對象建立時。就可以去連接指定主機。因爲tcp是面向連接的,所以在建立Socket服務時,就要有服務端存在並連接成功。形成通路後在該通道進行數據的傳輸。
步驟:
1、創建socket服務,並指定連接的主機和端口。
客戶端需要明確服務器的ip地址以及端口,這樣纔可以去試着建立連接,如果連接失敗,會出現異常。
連接成功,說明客戶端與服務端建立了通道,那麼通過IO流就可以進行數據的傳輸,而Socket對象已經提供了輸入流和輸出流對象,通過getInputStream(),getOutputStream()獲取即可。
與服務端通訊結束後,關閉Socket。
客戶端:通過Socket建立對象並指定要連接的服務端主機以及端口。
class TcpClient { public static void main(String[] args) throws Exception { //創建客戶端的socket服務,指定目地主機和端口。 Socket s = new Socket("192.168.1.100",10003);
//爲了發送數據,應該獲取Socket流中的輸出流。 OutputStream out = s.getOutputStream();
out.write("tcp ge men lai l ".getBytes());
s.close(); } } |
基本思路(服務端)
服務端需要明確它要處理的數據是從哪個端口進入的。
當有客戶端訪問時,要明確是哪個客戶端,可通過accept()獲取已連接的客戶端對象,並通過該對象與客戶端通過IO流進行數據傳輸。
當該客戶端訪問結束,關閉該客戶端。
步驟:
1、建立服務端的Socket服務,ServerSocket()//綁定端口。
並監聽一個端口,(打上數字標識。)
2、獲取連接過來的客戶端對象。
通過serverSocket的accept方法,沒有連接就會等。所以這個方法是阻塞式的。
3、客戶端如果發過來數據,那麼服務端要使用對應的客戶端對象,並獲取到該客戶端的讀取流來讀取發過來的數據。並打印在控制檯上。
4、關閉服務端。(可選)
服務端:建立服務端需要監聽一個端口。
class TcpServer { public static void main(String[] args) throws Exception { //建立服務端的Socket服務,並監聽一個端口 ServerSocket ss = new ServerSocket(10003);
//通過accept方法獲取連接過來的客戶端對象。 Socket s =ss.accept();
String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected");
//獲取客戶端發送過來的數據。要使用客戶端對象的讀取流方法來讀取數據。 InputStream in = s.getInputStream();//網絡流(源)。
byte[] buf = new byte[1024]; int len = in.read(buf);
System.out.println(new String(buf,0,len));
s.close();//關閉客戶端 //服務端不關自己,關對方。 ss.close(); } } |
Tcp傳輸最容易出現的問題:客戶端連接上服務端,兩端都在等待,沒有任何數據傳輸。
因爲read方法或者readLine方法是阻塞式方法。
解決辦法:
自定義結束標記
使用shutdownInput,shutdownOutput方法。
---------------------- android培訓、java培訓、期待與您交流! ----------------------
詳細請查看:http://edu.csdn.net/heima