擁塞控制和流量控制
- 接收方:流量控制
- 滑動窗口、避免發送方發包太快,超過接收方的緩存
發送方:擁塞控制
- 防止過多的數據注入到網絡中,承受網絡負荷
- 發送方維持cwnd(擁塞窗口),定義ssth(慢開始門限)
慢開始、擁塞避免、快重傳、快恢復
- cwnd < ssth,
1)慢開始
,cwnd=1,cwnd=cwnd*2 - cwnd>ssth,
2)擁塞避免
,cwnd=cwnd+1 - 收到3個相同ack
3)快重傳
,重傳ack序號+1分組;3)快恢復
,cwnd=ssth/2,2)擁塞避免
- 出現擁塞,ssth=cwnd/2,
1)慢開始
- cwnd < ssth,
三次握手listen()
維持一個監聽套接口的
未完成隊列
- 服務器已收到了來自客戶端的請求,三次握手的第一個分節到達
- 將它加入未完成隊列,然後響應三次握手的第二個分節
- 此時套接口處於
SYN-RCVD
狀態
維持一個監聽套接口的
已完成隊列
- 服務器已收到了來自客戶端的請求,三次握手的第三個分節到達
- 從未完成連接隊列移到已完成連接隊列的隊尾
- 套接口處於
ESTABLISHED
狀態
爲什麼用三次握手
- 若client沒收到第二個分節
- client不知道連接已經建立
- server認爲已建立,在一定時間內保留資源
- 如果大量的client請求,server會崩潰
爲啥使用四次揮手
- 客戶端,不再傳數據給服務器
- 服務器,不再傳數據給客戶端
public class SocketServer{
public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(2013);
boolean status=serverSocket.isBound();
System.out.println(status);
while (true){
Socket socket = serverSocket.accept();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine()) != null && line.length()!=0){
System.out.println(line);
}
String str="我阿德啊";str+="\n";
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
printWriter.print(str);
printWriter.flush();
bufferedReader.close();
printWriter.close();
}
}
}
public class SocketClient{
public static void main(String[] args) throws Exception{
Socket socket = new Socket("localhost", 2013);
socket.setSoTimeout(60000);
boolean status=socket.isBound();
System.out.println(status);
String str="我是醜東尼啊";str+="\n";
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true);
printWriter.print(str);
printWriter.flush();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine()) != null && line.length()!=0) {
System.out.println(line);
}
printWriter.close();
bufferedReader.close();
socket.close();
}
}