http协议下:为什么请求与响应会做到准确误的对应。不会出现请求与响应的错乱...
互聯網通信是套接字進行通信的,套接字,是支持TCP/IP的網絡通信的基本操作單元,可以看做是不同主機之間的進程進行雙向通信的端點,簡單的說就是通信的兩方的一種約定,用套接字中的相關函數來完成通信過程。
非常非常簡單的舉例說明下:套接字=Ip address+ TCP/UDP + port。
java 針對TCP 和 UDP進行了分別的開發封裝: Socket,DatagramSocket (早期 JAVA開發者沒有開發,DatagramSocket,TCP和UDP都是使用socket的進行開發的,后期加上了DatagramSocket后就把socket中開發UDP的API 廢棄了,
現在我們通常說socket開發tcp,DatagramSocket開發UDP)我們通常使用的互聯網開發都是tcp,http 建立在tcp之上的協議,即:一個請求一個響應,請求與響應
本質都是socket。也就是說socket與socket之間的通信,通信完畢就會結束鏈接,即無狀態的鏈接,即這次連接和下次連接都是獨立的交互。
請求與響應是一一對應的,不會出現A的響應給了B的請求,因為socket通信是靠四元組進行對接通信的
socket: 四元組 本地IP,本地Port,目標IP,目標Port
serversocket:本質也是socket,為了開發服務器這一角色,所以將socket封裝成了serversocket,創建serversocket的時候底層會創建一個socket,然后
會綁定這個socket,同時監聽這個socket的端口號并且會提前創建一個用于響應的socket。這樣就會做到其他的socket請求該serversocket中的socket,那么監聽器就會監聽到并觸發創建一個新的socket與請求socket進行通信,并且重新監聽(擴展:如果還沒有來的及從新監聽,就在這時,突然有大量的請求過來,那么此時服務器很有可能會崩潰也有你可能拒絕你的請求,此時就出現了消息中間件,比如kafka,activeMQ 等即,讓請求消息先來我這里排隊,拍好隊形在一個一個的去請求,這樣就不會突然出現高并發了,放在服務器受不了,最后一個簡單的案例說明。 )。并且會提前創建一個socket,等待請求。
源碼:
? public Socket accept() throws IOException {
? ? ? ? if (isClosed())
? ? ? ? ? ? throw new SocketException("Socket is closed");
? ? ? ? if (!isBound())
? ? ? ? ? ? throw new SocketException("Socket is not bound yet");
? ? ? ? Socket s = new Socket((SocketImpl) null); //提前創建好socket 響應
? ? ? ? implAccept(s); ?//當沒有請求時線程會停在這里,等待請求?
? ? ? ? return s;
? ? }
當客戶端創建請求socket時,Socket socket = new Socket("localhost",6472); 當請求socket鏈接到服務器時,socket才算創建成功,否者創建socket失敗并會
報錯:Exception in thread "main" java.net.ConnectException: Connection refused: connect
當請求socket創建成功后: 四元組 本地IP,本地Port,目標IP,目標Port 都會初始化完成,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 本地IP(假設為172.168.17.9),本地Port(java底層會隨機給一個未占用的port,假設為2635)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 目標IP(服務器的IP,假設為192.168.17.88),目標Port(服務器的端口 假設為 8080)?
此時accept()收到請求并且針對當前請求的socket返回一個響應socket,并且該響應socket的四元組 本地IP,本地Port,目標IP,目標Port
?都會初始化完成, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ??? ??? ??? ??? ??? ??? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 本地IP(服務器當前的IP:192.168.17.88),本地Port(java底層會隨機給一個未占用的port,假設為1526),
?? ??? ??? ??? ??? ??? ??? ??? ?目標IP(請求的IP:172.168.17.9)目標Port(請求的端口:2635 )?
此時,請求與響應才會做到了準備無誤的對應。才不會出現請求與響應的錯亂。
demo:
package com.jvm.others.socket_;
import java.net.Socket;
public class Demo2Soket { //客戶端
?? ?public static void main(String[] args) throws Exception {
?? ??? ?Socket socket = new Socket("localhost",6478);
?? ??? ?String hostAddress = socket.getLocalAddress().getHostAddress();
?? ??? ?int localPort = socket.getLocalPort();
?? ??? ?SocketUtiles.pringHostAndPort(socket);
?? ?}
}
客戶端打印結果:
? ? ?Local socket Host : 127.0.0.1
? ? ?Local socket HostAddress : 127.0.0.1
? ? ?Local socket Port : 60737
? ? ?des socket Host : localhost
? ? ?des socket HostAddress : 127.0.0.1
? ? ?des socket Port : 6478
? ? ?當前請求時間 15 5944
package com.jvm.others.socket_;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
public class Demo2ServerSocket { //服務器
?? ? ?public static void main(String[] args) throws Exception {
?? ??? ?ServerSocket ss = new ServerSocket(6478);
?? ??? ?while(true){
?? ??? ?Socket accept = ss.accept();
?? ??? ?SocketUtiles.pringHostAndPort(accept);
?? ??? ?}
?? ? ? ? }
}
服務器打印方式:
? ? ? ?Local socket Host : 127.0.0.1
? ? ? ?Local socket HostAddress : 127.0.0.1
? ? ? ?Local socket Port : 6478
? ? ? ?des socket Host : 127.0.0.1
? ? ? ?des socket HostAddress : 127.0.0.1
? ? ? ?des socket Port : 60737
? ? ? ?當前請求時間 15 5944
擴展代碼?? ? ??
并發案例服務器受不了拒絕了你:
package com.jvm.others.socket_;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
//模擬客戶端請求
public class DemoSocket {
?? ?public static void main(String[] args) throws Exception {
?? ??? ?for(int i = 0;i<1000;i++){
?? ??? ?Socket socket = new Socket("localhost",6466);
?? ??? ?String hostAddress = socket.getLocalAddress().getHostAddress();
?? ??? ?int localPort = socket.getLocalPort();
?? ??? ?SocketUtiles.pringHostAndPort(socket);
?? ??? ?}
?? ?}
}
package com.jvm.others.socket_;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
//模擬服務器
public class DemoSocketServer {
?? ?static int i= 1;
? public static void main(String[] args) throws Exception {
?? ?ServerSocket ss = new ServerSocket(6466);
?? ?while(true){
?? ?Socket accept = ss.accept();
?? ?if(i==1){
?? ??? ?Date date = new Date();
?? ??? ?System.out.println("開始睡覺 當前時間為 : "+date.getHours()+" "+date.getMinutes()+" "+date.getSeconds());
?? ? ? Thread.sleep(4000); //模擬來不及監聽,停了4秒
?? ? ? Date date2 = new Date();
?? ? ? ?System.out.println("睡覺結束 當前時間為 : "+date2.getHours()+" "+date2.getMinutes()+" "+date.getSeconds());
?? ?}
?? ?i++;
?? ?SocketUtiles.pringHostAndPort(accept);
?? ?}
? ? ?}
}
//工具類 ?
package com.jvm.others.socket_;
import java.net.Socket;
import java.util.Date;
public class SocketUtiles {
?? ?public ?static void pringHostAndPort(Socket s){
?? ??? ?Date date = new Date();
?? ??? ?System.out.println(" Local socket Host : "+s.getLocalAddress().getHostName());
?? ??? ?System.out.println(" Local socket HostAddress : "+ s.getLocalAddress().getHostAddress());
?? ??? ?System.out.println(" Local socket Port : "+s.getLocalPort());
?? ??? ?System.out.println(" ?des socket Host : "+s.getInetAddress().getHostName());
?? ??? ?System.out.println(" ?des socket HostAddress : "+ s.getInetAddress().getHostAddress());
?? ??? ?System.out.println(" ?des socket Port : "+s.getPort());
?? ??? ?System.out.println("當前請求時間 "+date.getHours()+" "+date.getMinutes()+date.getSeconds());
?? ?}
}
請求客戶端會報Exception in thread "main" java.net.ConnectException: Connection refused: connect 拒絕鏈接。
總結
以上是生活随笔為你收集整理的http协议下:为什么请求与响应会做到准确误的对应。不会出现请求与响应的错乱...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 车牌是什么 了解车牌的含义和种类?
- 下一篇: 克拉玛依蚊子怎么这么多