一.網絡通信的原理。
這就是OSI模型,我們要進行網絡傳輸,對於我們而言或許只知道發送和接收數據,並不知道,他的原理是什麼。我認爲網絡傳輸的過程分爲三個:發送方數據的包裝,物理層發送,接收方的拆包。
1.發送方的數據包裝。
當我們的應用產生數據要傳送,首先要經過應用層按照應用層特有的方式進行包裝,接着傳遞給表示層,表示層再按照它特有的方法進行包裝,以此類推,直到到了物理層。就相當於你在淘寶上買東西,商家把你的東西包裝好了並且加了密碼交給物流。
2.當數據到達了物理層,也就是網絡傳輸介質例如,光纖,無線介質等。他們會根據傳送過來的數據的要求進行傳輸,也就相當於物流開始傳輸送數據。
3.接收方接收數據進行拆包。當物理層把數據傳到接收方,接收方接到數據後,會按照發送方包裝的倒序進行拆包,很簡單,當你收到數據後肯定要先打開最外面的包裝嘍。當然,接收方和發送方所用的方法都是一樣的,否則無法打開,或者會破壞數據。直到數據傳輸到應用層。
二,TCP,UDP的比較。
TCP:
1.建立連接,形成傳輸的通道。
2.在連接中會進行大量數據的傳輸。
3.通過三次握手完成連接,是可靠的。
4.因爲必須建立連接,所以效率會很低。
UDP:
1.將數據及源和目的封裝在數據包中,不需要建立連接。
2.每個數據報的大小必須限制在64K內。
3.無需建立連接,是不可靠的協議。
4.因爲不需要建立連接,所以傳輸速度快。
三.TCP傳輸.
TCP傳輸的雙方,我們稱之爲,客戶端和服務器端。
客戶端(Client)是指網絡編程中首先發起連接的程序,客戶端一般實現程序界面和基本邏輯實現,在進行實際的客戶端編程時,無論客戶端複雜還是簡單,以及客戶端實現的方式,客戶端的編程主要由三個步驟實現:
1、 建立網絡連接
客戶端網絡編程的第一步都是建立網絡連接。在建立網絡連接時需要指定連接到的服務器的IP地址和端口號,建立完成以後,會形成一條虛擬的連接,後續的操作就可以通過該連接實現數據交換了。
2、 交換數據
連接建立以後,就可以通過這個連接交換數據了。交換數據嚴格按照請求響應模型進行,由客戶端發送一個請求數據到服務器,服務器反饋一個響應數據給客戶端,如果客戶端不發送請求則服務器端就不響應。
根據邏輯需要,可以多次交換數據,但是還是必須遵循請求響應模型。
3、 關閉網絡連接
在數據交換完成以後,關閉網絡連接,釋放程序佔用的端口、內存等系統資源,結束網絡編程。
最基本的步驟一般都是這三個步驟,在實際實現時,步驟2會出現重複,在進行代碼組織時,由於網絡編程是比較耗時的操作,所以一般開啓專門的現場進行網絡通訊。
服務器端(Server)是指在網絡編程中被動等待連接的程序,服務器端一般實現程序的核心邏輯以及數據存儲等核心功能。服務器端的編程步驟和客戶端不同,是由四個步驟實現,依次是:
1、 監聽端口
服務器端屬於被動等待連接,所以服務器端啓動以後,不需要發起連接,而只需要監聽本地計算機的某個固定端口即可。
這個端口就是服務器端開放給客戶端的端口,服務器端程序運行的本地計算機的IP地址就是服務器端程序的IP地址。
2、 獲得連接
當客戶端連接到服務器端時,服務器端就可以獲得一個連接,這個連接包含客戶端的信息,例如客戶端IP地址等等,服務器端和客戶端也通過該連接進行數據交換。
一般在服務器端編程中,當獲得連接時,需要開啓專門的線程處理該連接,每個連接都由獨立的線程實現。
3、 交換數據
服務器端通過獲得的連接進行數據交換。服務器端的數據交換步驟是首先接收客戶端發送過來的數據,然後進行邏輯處理,再把處理以後的結果數據發送給客戶端。簡單來說,就是先接收再發送,這個和客戶端的數據交換數序不同。
其實,服務器端獲得的連接和客戶端連接是一樣的,只是數據交換的步驟不同。
當然,服務器端的數據交換也是可以多次進行的。
在數據交換完成以後,關閉和客戶端的連接。
4、 關閉連接
當服務器程序關閉時,需要關閉服務器端,通過關閉服務器端使得服務器監聽的端口以及佔用的內存可以釋放出來,實現了連接的關閉。
1.簡單的通過域名獲取IP和主機名的方法。
import java.net.InetAddress;
public class ipclass {
public static void main(String[] args) throws Exception {
// InetAddress 類提供將主機名解析爲其 IP 地址(或反之)的方法。
InetAddress inetAddress=InetAddress.getByName("www.baidu.com");
//通過getHostAddress()
System.out.println("ip:"+inetAddress.getHostAddress());
//通過getHostName()
System.out.println("host:"+inetAddress.getHostName());
}
}
2.TCP例子
import java.io.OutputStream;
import java.net.Socket;
public class TCPClient {//客戶端
public static void main(String[] args) throws Exception{
//創建客戶端的socket服務,並制定目標主機和端口
Socket socket=new Socket("192.168.5.127",8888);
//打開輸出流
OutputStream outputStream=socket.getOutputStream();
outputStream.write("我爲字母狂".getBytes());
//關閉服務
socket.close();
}
}
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {//服務器端
public static void main(String[] args) throws Exception{
//建立服務器端socket服務,並監聽一個端口
ServerSocket serverSocket=new ServerSocket(8888);
//通過accept()獲取鏈接過來的客戶端的socket對象
Socket socket=serverSocket.accept();
String ip=socket.getInetAddress().getHostAddress();
System.out.println("ip:"+ip);
//獲取客戶端發過來的數據
InputStream inputStream=socket.getInputStream();
byte[] buf=new byte[1024];
int len=inputStream.read(buf);
System.out.println(new String(buf,0,len));
//關閉客戶端
socket.close();
//關閉服務器端
serverSocket.close();
}
}