目錄
- 1 TCP
-
- 1.1 TCP簡介
- 1.2 TCP連接配接方式
- 2 代碼實作
-
- 2.1 準備工作
-
- 2.1.1 檢視本機IP位址
- 2.2 用戶端
- 2.3 伺服器端
- 3 運作
-
- 3.1 運作操作
- 3.2 步驟運作
- 3.3 運作截圖
1 TCP
1.1 TCP簡介
傳輸控制協定(TCP,Transmission Control Protocol)是一種面向連接配接的、可靠的、基于位元組流的傳輸層通信協定,由IETF的RFC 793 [1] 定義。
TCP旨在适應支援多網絡應用的分層協定層次結構。 連接配接到不同但互連的計算機通信網絡的主計算機中的成對程序之間依靠TCP提供可靠的通信服務。TCP假設它可以從較低級别的協定獲得簡單的,可能不可靠的資料報服務。 原則上,TCP應該能夠在從硬線連接配接到分組交換或電路交換網絡的各種通信系統之上操作。
1.2 TCP連接配接方式
tcp連接配接方式俗稱為"三次握手”即:
第一次
第一次握手:建立連接配接時,用戶端發送syn包(seq=j)到伺服器,并進入SYN_SENT狀态,等待伺服器确認;SYN:同步序列編号(Synchronize Sequence Numbers)。
第二次
第二次握手:伺服器收到syn包,必須确認用戶端的SYN(ack=j+1),同時自己也發送一個SYN包(seq=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀态。
第三次
第三次握手:用戶端收到伺服器的SYN+ACK包,向伺服器發送确認包ACK(ack=k+1),此包發送完畢,用戶端和伺服器進入ESTABLISHED(TCP連接配接成功)狀态,完成三次握手。
完成三次握手,用戶端與伺服器開始傳送資料。

2 代碼實作
2.1 準備工作
2.1.1 檢視本機IP位址
打開cmd指令提示符,輸入ipconfig即可檢視本機IP位址。
2.2 用戶端
注意:Socket s = new Socket(“192.168.88.104”, 10005);
IP位址為自己本機IP,端口号合适範圍内即可,但端口号須與伺服器端保持一緻。
package tcp06;
import java.io.*;
import java.net.Socket;
public class ClientDemo06 {
public static void main(String[] args) throws IOException {
//建立用戶端Socket對象
Socket s = new Socket("192.168.88.104", 10005);
//封裝文本檔案的資料
BufferedReader br = new BufferedReader(new FileReader("L:\\Java\\tcp\\lcc.txt"));
//封裝輸出流資料
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
//自定義結束标記
// bw.write("886");
// bw.newLine();
// bw.flush();
//public void shutdownOutput()
s.shutdownOutput();//資料結束
//接收回報
BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
String data = brClient.readLine();
System.out.println("伺服器回報:" + data);
//釋放資源
br.close();
bw.close();
}
}
2.3 伺服器端
注意:ServerSocket ss = new ServerSocket(10005);
端口号須與用戶端端保持一緻
package tcp06;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo06 {
public static void main(String[] args) throws IOException {
//建立伺服器對象
ServerSocket ss = new ServerSocket(10005);
while (true) {
//監聽用戶端連接配接,傳回一個對應的Socket對象
Socket s = ss.accept();
//為每個用戶端開啟一個線程
new Thread(new ServerThread(s)).start();
}
//ss.close();//一般來說伺服器是不關閉的
}
}
通過實作Runnable接口的方法實作多線程
package tcp06;
import java.io.*;
import java.net.Socket;
public class ServerThread implements Runnable {
private Socket s;
public ServerThread(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
//接收資料寫入文本檔案
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//BufferedWriter bw = new BufferedWriter(new FileWriter("day01\\3.txt"));
//解決名稱沖突問題
int count = 0;
File file = new File("day01\\TX" + count + ".txt");
while (file.exists()) {
count++;
file = new File("day01\\TX" + count + ".txt");
}
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
//給出回報
BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bwServer.write("檔案上傳成功");
bwServer.newLine();
bwServer.flush();
//釋放資源
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3 運作
3.1 運作操作
先打開伺服器端,再打開用戶端。
3.2 步驟運作
1.用戶端先讀取L:\Java\tcp\lcc.txt内容,然後寫入資料發送給伺服器端。
2.伺服器端讀取用戶端發送的資料寫入相應檔案我寫的是本子產品day01下的路徑),并給用戶端發送回報。
3.用戶端接收并輸出回報。
3.3 運作截圖
這是原本子產品下的檔案:
運作用戶端
通過多線程執行多個用戶端結果:
檢視資料,OK沒問題。