1.什麼是網絡、計算機網絡的構成是什麼?
在計算領域中,網絡是傳輸信息、接受、共享的虛擬的平臺。
通過它可以把各個點、面、體的信息聯繫到一起,從而實現這些資源的共享。
網絡是人類發展史上最重要的發明,提高了人類和科技的一個發展。
2.什麼是網絡編程?
網絡編程從大的方面就是說對信息的發送接收。
通過操作相應API調度計算機資源硬件,並且利用管道(網線)進行數據交互的過程。
更爲具體的涉及:網絡模型、套接字、數據包
3. 7層網絡模型--OSI
基礎層:物理層(physical)、數據鏈路層(Datalink)、網絡層(network).。
傳輸層(Transport):TCP-UDP協議層、Socket。
高級層::會話層(Session)、表示層(Presentation)、應用層(Application)
4. 網絡模型---對應關係
5.Socket與TCP、UDP
Socket: 簡單來說是ip地址與端口的結合協議(RFC 793).
一種地址與端口的結合描述協議。
TCP/IP協議的相關API的總稱;是網絡API的集合實現.
涵蓋了Stream socket /Datagram Socket
socket 的組成與作用:
在網絡傳輸中用於唯一標識兩個端點的鏈接。
端點:包括(ip+port)
4個要素:客戶端的地址、客戶端的端口、服務器的地址、服務器端口。
6. Socket的傳輸原理
Socket之TCP:
tcp是面向連接的通訊協議。
通過三次握手建立連接,通訊完成時要拆除連接。
由於TCP是面向連接的,所以只能用於端到端的通信。
Socket之UDP:
UDP是面向無連接進行通訊的。
UDP數據包括目的端口號和源端口號信息。
由於通訊時是不需要連接,所以可以是實現廣播發送,並不侷限於端到端。
TCP傳輸圖解:
UDP傳輸圖解:
7.Client-Server Application
TCP/IP協議中,兩個進程間通信的主要模式爲CS模型
主要的目的:協調網絡中計算機資源、服務模式、進程間數據共享
常見的FTP、SMTP、HTTP
8.報文段
報文段是指TCP/IP協議網絡傳輸過程中,起着路由導航作用。
可以查詢各個網絡路由網段、IP地址、交換協議等ip數據包。
報文段充當整個TCP/IP協議數據包的導航路由功能。
報文在傳輸過程中會不斷的封裝成分組、包、幀來傳輸。
封裝的方式就是添加一些控制信息組成的首部,即報文頭。
9.傳輸協議
一種約定,約束
約定大於配置,在網絡傳輸中依然食用;網絡的傳輸是健壯的穩定的,得益於基礎的協議構成。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @Author: itwang @Description: @Date: Created in 22:40 2018/12/29 @Package: PACKAGE_NAME @Modified
* By:
*/
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(2000);
System.out.println("服務器準備就緒----");
System.out.println(
"服務器信息:" + serverSocket.getInetAddress() + "p:" + serverSocket.getLocalPort());
for (; ; ) {
// 等待客戶端連接
Socket client = serverSocket.accept();
// 客戶端構建異步線程
ClientHandler clientHandler = new ClientHandler(client);
// 啓動線程
clientHandler.start();
}
// todo(client);
}
/** 客戶端消息處理 */
private static class ClientHandler extends Thread {
private Socket socket;
private boolean flag = true;
ClientHandler(Socket socket) {
this.socket = socket;
}
/**
* If this thread was constructed using a separate <code>Runnable</code> run object, then that
* <code>Runnable</code> object's <code>run</code> method is called; otherwise, this method does
* nothing and returns.
*
* <p>Subclasses of <code>Thread</code> should override this method.
*
* @see #start()
* @see #stop()
* @see #(ThreadGroup, Runnable, String)
*/
@Override
public void run() {
super.run();
System.out.println("客戶端連接:" + socket.getInetAddress() + "p:" + socket.getPort());
try {
// 得到打印流,用於服務器輸出;服務端回送數據
PrintStream socketOutPut = new PrintStream(socket.getOutputStream());
// 得到輸入流
BufferedReader socketInput =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
do {
// 從客戶端拿到一條數據
String str = socketInput.readLine();
if ("bye".equalsIgnoreCase(str)) {
flag = false;
// 回送
socketOutPut.println("bye");
} else {
// 打印到屏幕並回送數據長度
System.out.println(str);
socketOutPut.println("回送:" + str.length());
}
} while (flag);
socketInput.close();
socketOutPut.close();
} catch (Exception e) {
System.out.println("連接異常斷開");
} finally {
// 連接關閉
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("客戶端關閉" + socket.getInetAddress() + "p" + socket.getPort());
}
}
}
;
import java.io.*;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
* @author : itwang
* @description:
* @date: Created in 22:40 2018/12/29
* @package: PACKAGE_NAME
* @modified By:
*/
public class Client {
public static void main(String[] args) throws IOException {
// 創建socket
Socket socket = new Socket();
// 設置超時時間
socket.setSoTimeout(3000);
socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000));
System.out.println("已經發起服務器連接,並進入後續流程");
System.out.println("客戶端信息:" + socket.getLocalAddress() + "p:" + socket.getLocalPort());
System.out.println("服務端信息:" + socket.getInetAddress() + "P" + socket.getPort());
try {
todo(socket);
} catch (Exception e) {
System.out.println("異常關閉");
}
// 釋放資源
socket.close();
System.out.println("客戶端退出");
}
private static void todo(Socket client) throws IOException {
// 構建鍵盤輸入流
InputStream in = System.in;
BufferedReader input = new BufferedReader(new InputStreamReader(in));
// 得到socket輸出流,並且轉化爲打印流
OutputStream outputStream = client.getOutputStream();
PrintStream socketPrintStream = new PrintStream(outputStream);
// 得到socket輸入流,並轉化爲bufferedReader
InputStream inputStream = client.getInputStream();
BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(inputStream));
boolean flag = true;
do {
// 鍵盤讀取一行
String str = input.readLine();
// 發送到服務器
socketPrintStream.println(str);
// 從服務器讀取一行
String echo = socketBufferedReader.readLine();
if ("bye".equalsIgnoreCase(echo)) {
flag = false;
} else {
System.out.println(echo);
}
} while (flag);
// 資源釋放
socketPrintStream.close();
socketBufferedReader.close();
}
}