一.網絡編程
網絡模型:
OSI參考模型:應用層、表示層、會話層、傳輸層、網絡層、鏈路層、物理層
TCP/IP參考模型:
應用層:FTP,HTTP
傳輸層:UDP協議和TCP協議
網際層:
主機至網絡層
二.網絡通訊要素
a) IP地址:網絡設備標識
類:InetAddress
InetAddress I = InetAdress.getLocalHost();
//結果是主機名和IP地址
System.out.println(i.toString);
//結果是IP地址
System.out.println(“address:”+i.getHostAddress());
//結果是主機名
System.out.println(“name:”+i.getHostName());
InetAddress ia = InetAddress.getByName(“www.baidu.com”);
System.out.println(“address:”+ia.getHostAddress());
System.out.println(“name:”+ia.getHostName());
b) 端口號:有效端口:0~65535,其中0~1024系統使用或保留端口
c) 傳輸協議:
通訊的規則
常見協議:TCP和UDP
UDP: 將數據及源和目的封閉成數據包中,不需要建立連接
每個數據報的大小在限制在64k內
因無連接,是不可靠協議
不需要建立連接,速度快
1.面向無連接,2. 數據會被封包,有限制64k內,3.不可靠。4. 速度快
TCP: 建立連接,形成傳輸數據的通道。
在連接中進行大數據量傳輸
通過三次握手完成連接,是可靠協議
必須建立連接,效率會稍低
三. Socket
爲網絡服務提供的一種機制,通信的兩端都有Socket,網絡通信其實就是Socket間的通信。數據在兩個Socket間通過IO傳輸。
UDP傳輸
DatagramSocket (此類表示用來發送和接收數據報包的套接字)
receive(DatagramPacketp):接收
send(DatagramPacketp):發送
DatagramPacket(此類表示數據報包)
實例:
需求:通過UDP傳輸方式,將一段文字數據發送出去
1. 建立udpscoket服務。
2. 提供數據,並將數據封閉到DatagramPacket
3. 通過socket服務的發送功能,將數據包發出支。
4. 關於資源
DatagramSocketds = new DatagramSocket();
byte[]buf = “udp ge men lai le”.getBytes();
DatagramPacketdp = new DatagramPacket(buf,buf.length,InetAddress.getByName(“127.0.0.1”),10000);
ds.send(dp);
ds.close();
需求:用於接收udp傳輸的數據並處理
1. 定義udpsocket服務。通常會監聽一個端口,其實就是給這個接收網絡應用程序定義數據標識,如果沒有定義,系統會自動分配一個。方便於明確哪些數據過來該應用程序可以處理。
2. 定義一個空的數據包,因爲要存儲接收到的字節數據,因爲數據包對象中有更多功能可以提取字節數據中不同數據信息。
3. 通過socket服務的receive方法將收到的數據存入已定義好的數組中。
4. 通過數據包對象的特有功能,將這些不同的數據取出,打印出來。
5. 關閉資源
DatagramSocket ds = new DatagramSocket(10000);
byte[]buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip = dp.getAddress.().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+”::”+data+”::”+port);
ds.close();
發送端如果要一直處於等待狀態的話。加while語句
BindException:端口已經被使用,綁定異常。
1024*64,數據包最大值
需求:編寫一個聊天程序。
有收數據和發數據的部分,這兩部分需要同時執行,那就需要用到多線程技術。一個線程控制收,另一個線程控制發
因爲收和發動作是不一致的。所以要定義兩個run方法,而且這兩個方法要封閉到不同的類中。
TCP傳輸
Socket和ServerSocket: 建立客戶端和服務器端
實例:
客戶端: 通過查閱socket對象,發現在該對象建立時,就可以去連接指定主機。因爲tcp是面向連接的,所以在建立socket服務時,就要有服務端存在,並連接成功。形成通路後,在該通道進行數據的傳輸。
需求:給服務端發送一個文本數據。
步驟:
1. 創建socket服務,並指定要連接的主機和端口。
Socket s= new Socket(“192.168.1.254”,10003);
2. 爲了發送數據,應該獲取socket流中的輸出流。
OutputStreamou t = s.getOutputStream();
out.write(“sfdasfsaddsaf”.getBytes());
3. 關閉服務
s.close();
服務端:
需求:定義端點接收數據並打印在控制檯上。
1. 建立服務器端 的socket服務。ServerSocket();並監聽一個端口。
2. 獲取連接過來的客戶端對象。通過ServerSocket的accept()方法獲取Socket對象。沒有連接就會等,這個方法是阻塞式的。
3. 客戶端如果發過來數據,那麼服務端要使用對應的客戶端對象,並獲取到該客戶端對象的讀取流來讀取發過來的數據。
4. 關閉服務端。(可選,一般不關閉)
ServerSocketss = new ServerSocket(10003);
Socket s= ss.accept();
String ip= s.getInetAddress().getHostAddress();
System.out.println(ip+“connected…”);
InputStreamin = s.getInputStream();
byte[]buf = new byte[1024];
int len =in.read(buf);
System.out.println(newString(buf,0,len));
s.close();
ss.close();
演示tcp的傳輸的客戶端和服務端的互訪。
需求:客戶端給服務端發送數據,服務端收到後,給客戶端反饋信息。
客戶端:
1. 建立socket服務,指定要連接主機和端口。
2. 獲取socket流中的輸出流,將數據寫到該流中,通過網絡發送給服務端。
3. 獲取socket流中的輸入流,將服務端反饋的數據獲取到並打印。
4. 關閉客戶端資源。
Socket s= new Socket(“192.168.1.254”,10004);
OutputStreamout = s.getOutputStream();
out.write(“服務端,您好”.getBytes());
InputStreamin = s.getInputStream();
byte[]buf = new byte[1024];
int len =in.read(buf);
System.out.println(newString(buf,0,len));
s.close();
服務端
ServerSocketss = new ServerSocket(10004);
Socket s= ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+”…..connected”);
InputStreamin = s.getInputStream();
byte[]buf = new byt[1024];
int len =in.read[buf];
system.out.println(newString(buf,0,len));
OutputStreamout = s.getOutputStream();
out.write(“你也好”.getBytes());
ss.close();
實例:上傳圖片
客戶端:
1,服務端點
2,讀取客戶端已有的圖片數據
3,通過Socket輸出流將數據發給服務端
4,讀取服務端反饋信息
5,關閉
服務端:
這個服務端有個侷限性,當A 客戶端連接上以後,被服務端獲取到。服務端執行具體流程,這時B客戶端連接只有等待A執行完。因爲服務端還沒處理完A客戶端的請求,還沒有循環回來執行下次的accept方法,所以暫時獲取不到B客戶堅象。那麼爲了可以讓多個客戶端同時併發訪問服務端,那麼服務端最好就是將每個客戶端封裝到一個單獨的線程中。這樣,就可以同時處理多個客戶端的請求。
如何定義線程呢?
只要明確了每一個客戶端要在服務端執行的代碼即可。將該代碼存入run方法中。
客戶端併發登錄
瀏覽器客戶端-自定義服務端
瀏覽器客戶端-Tomcat服務器
HTTP頭
可以利用HTTP頭自定義客戶端向Tomcat服務器發送請求信息
http://192.168.1.254:11000/myweb/demo.html
GET/myweb/demo.html HTTP/1.1
Accept:application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, i
mage/pjpeg,application/vnd.ms-excel, application/vnd.ms-powerpoint, application
/msword,application/QVOD, application/QVOD,
Accept-Language:zh-cn
Accept-Encoding:gzip, deflate
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0
.50727)
Host:192.168.1.254:11000
Connection:Keep-Alive
//回車
//發送的內容
URL類
URI比URL範圍大,包括條形碼
包括很多獲取服務器信息的方法
getFile()文件名
getHost()主機名
getPath()路徑部分
getPort();端口號
getProtocol();協義名稱
getQuery(); 獲取此URL的查詢部
URLConnection
URLConnection urlc = url.openConnection();
URL url = new URL(“http://localhost:8080/web/aa.html”);
URLConnection urlc = url.openConnection();
InputStream is = urlc.getInputStream();
...........
//不需要用Socket了。因爲現在走的是應用層, 當服務器返回時,http響應信息會在傳輸層過濾掉!
Socket()一個無參數的構造函數
.connect(SocketAddress endpoint) 連接服務器
ServerSocket(int port , int backlog):backlog:同時在線的客戶端連接數
域名解析:
首先會訪問一個DNS域名解析服務器,在DNS域名解析服務器中查找baidu的IP地址
本機的映射關係在於host文件中