国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用Socket技術(shù)進(jìn)行數(shù)據(jù)傳輸、傳輸文件;瀏覽器訪問(wèn)Socket服務(wù)器

這篇具有很好參考價(jià)值的文章主要介紹了使用Socket技術(shù)進(jìn)行數(shù)據(jù)傳輸、傳輸文件;瀏覽器訪問(wèn)Socket服務(wù)器。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

計(jì)算機(jī)網(wǎng)絡(luò)基礎(chǔ)

利用通信線路和通信設(shè)備,將地理位置不同的、功能獨(dú)立的多臺(tái)計(jì)算機(jī)互連起來(lái),以功能完善的網(wǎng)絡(luò)軟件來(lái)實(shí)現(xiàn)資源共享和信息傳遞,就構(gòu)成了計(jì)算機(jī)網(wǎng)絡(luò)系統(tǒng)

IP地址和端口

通過(guò)IP地址,區(qū)分不同的計(jì)算機(jī)

每一臺(tái)電腦在一個(gè)網(wǎng)絡(luò)上擁有一個(gè)獨(dú)屬于自己的IP地址,用于區(qū)別其他電腦,可以通過(guò)對(duì)方的IP地址進(jìn)行訪問(wèn);所以當(dāng)我們的手機(jī)開(kāi)著流量的時(shí)候,是無(wú)法訪問(wèn)連著WIFI的電腦的

電腦上運(yùn)行的大量程序可能需要通過(guò)網(wǎng)絡(luò)來(lái)訪問(wèn)其他計(jì)算機(jī),這時(shí)通過(guò)端口號(hào)來(lái)進(jìn)行區(qū)分

socket 發(fā)送文件,JavaWeb,tcp/ip,udp

因此一般看到的是地址都是IP:port形式訪問(wèn)目標(biāo)主機(jī)的一個(gè)應(yīng)用程序,端口號(hào)的值為[0, 65535]

IP地址分為IPv4和IPv6,IPv4類似于192.168.0.11,上面提到的例子都是使用的IPv4,它一共有四組數(shù)字,每組數(shù)字占8個(gè)bit位,IPv4地址0.0.0.0表示為2進(jìn)制就是:00000000.00000000.00000000.00000000,共32個(gè)bit,最大為255.255.255.255

IPv6能夠保存128個(gè)bit位,因此它也可以表示更多的IP地址,一個(gè)IPv6地址看起來(lái)像這樣:1030::C9B4:FF12:48AA:1A2B,目前也正在向IPv6的階段過(guò)渡

TCP和 UDP

  • TCP:當(dāng)一臺(tái)計(jì)算機(jī)想要與另一臺(tái)計(jì)算機(jī)通訊時(shí),兩臺(tái)計(jì)算機(jī)之間的通信需要暢通且可靠(會(huì)進(jìn)行三次握手,斷開(kāi)也會(huì)進(jìn)行四次揮手),這樣才能保證正確收發(fā)數(shù)據(jù),因此TCP更適合一些可靠的數(shù)據(jù)傳輸場(chǎng)景
  • UDP:它是一種無(wú)連接協(xié)議,數(shù)據(jù)不會(huì)建立可靠傳輸,傳輸過(guò)程中有可能會(huì)導(dǎo)致部分?jǐn)?shù)據(jù)丟失,但是它比TCP傳輸更加簡(jiǎn)單高效,適合視頻直播之類的

socket 發(fā)送文件,JavaWeb,tcp/ip,udp

Socket技術(shù)

通過(guò)Socket技術(shù)(它是計(jì)算機(jī)之間進(jìn)行通信一種約定或一種方式),可以實(shí)現(xiàn)兩臺(tái)計(jì)算機(jī)之間的通信,Socket也被翻譯為套接字,是操作系統(tǒng)底層提供的一項(xiàng)通信技術(shù),它支持TCP和UDP。而Java就對(duì)socket底層支持進(jìn)行了一套完整的封裝,因此可以通過(guò)Java來(lái)實(shí)現(xiàn)Socket通信。

要實(shí)現(xiàn)Socket通信,需創(chuàng)建一個(gè)數(shù)據(jù)發(fā)送者和一個(gè)數(shù)據(jù)接收者,也就是客戶端和服務(wù)端,我們需要提前啟動(dòng)服務(wù)端,來(lái)等待客戶端的連接,而客戶端只需要隨時(shí)啟動(dòng)去連接服務(wù)端即可

//服務(wù)端
public static void main(String[] args) {
    try(ServerSocket server = new ServerSocket(8080)){    //將服務(wù)端創(chuàng)建在端口8080上
        System.out.println("正在等待客戶端連接...");
        Socket socket = server.accept();  //當(dāng)沒(méi)有客戶端連接時(shí),線程會(huì)阻塞,直到有客戶端連接為止
        System.out.println("客戶端已連接,IP地址為:"+socket.getInetAddress().getHostAddress());
    }catch (IOException e){
        e.printStackTrace();
    }
}

用戶端

public static void main(String[] args) {
    try (Socket socket = new Socket("localhost", 8080)){
        System.out.println("已連接到服務(wù)端!");
    }catch (IOException e){
        System.out.println("服務(wù)端連接失?。?);
        e.printStackTrace();
    }
}

實(shí)際上他是一個(gè)TCP連接的過(guò)程,一旦連接建立,只要客戶端不主動(dòng)關(guān)閉,整個(gè)程序就不會(huì)停止運(yùn)行;服務(wù)端也不僅僅支持一個(gè)客戶端,在同一網(wǎng)絡(luò)的前提下,可以連接多個(gè)服務(wù)端

public static void main(String[] args) {
	try(ServerSocket server = new ServerSocket(8080)) { //port,也就是端口號(hào)為8080
        System.out.println("等待連接...");
        while(true) {
            Socket s = server.accept(); //無(wú)限循環(huán)等待客戶端的連接
            System.out.println("IP地址為:" + socket.getInetAddress().getHostAddress());
        }
    }catch(IOException e) {
        e.printStackTrace();
    }
}

使用Socket進(jìn)行數(shù)據(jù)傳輸

通過(guò)Socket對(duì)象,我們就可以獲取到對(duì)應(yīng)的I/O流進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)傳輸:

服務(wù)端

//Server端
public class server {
    public static void main(String[] args) {
        try(ServerSocket server = new ServerSocket(8080)){ //try-with-resource語(yǔ)句,自動(dòng)關(guān)閉,不需要close
            System.out.println("正在等待客戶端連接:");
            Socket socket = server.accept();
            socket.setSoTimeout(5000); // timeout
            System.out.println("客戶端已連接,IP地址為:" + socket.getInetAddress().getHostAddress());
            System.out.println("讀取客戶端數(shù)據(jù):");
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println("內(nèi)容為:" + reader.readLine());

            OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
            writer.write("收到\n");
            writer.flush();
            socket.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

用戶端

public class Main {
    public static void main(String[] args) {
        try(Socket s = new Socket("localhost", 8080);
            Scanner sc = new Scanner(System.in)){
            System.out.println("已連接到服務(wù)區(qū)");
            OutputStreamWriter writer = new OutputStreamWriter(s.getOutputStream()); //讀取發(fā)送內(nèi)容
            writer.write(sc.nextLine() + "\n"); //加換行符是讀取需要
            writer.flush();
            s.shutdownOutput();
            System.out.println("數(shù)據(jù)已發(fā)送");

            BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
            System.out.println("收到服務(wù)端響應(yīng):" + reader.readLine());
        }catch(IOException e) {
            System.out.println("連接失敗");
            e.printStackTrace();
        }finally {
            System.out.println("斷開(kāi)連接");
        }
    }
}

先啟動(dòng)Server端,再啟動(dòng)用戶端;127.0.0.1是自己電腦

手動(dòng)關(guān)閉單向的流:

socket.shutdownOutput(); //輸出方向關(guān)閉
socket.shutdownInput(); //關(guān)閉輸入方向

可以通過(guò)調(diào)用setSoTimeout()方法來(lái)設(shè)定IO超時(shí)時(shí)間:

socket.setSoTimeout(3000);

當(dāng)超過(guò)設(shè)定時(shí)間都依然沒(méi)有收到客戶端或是服務(wù)端的數(shù)據(jù)時(shí),會(huì)拋出異常:

java.net.SocketTimeoutException: Read timed out
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:171)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
	at java.io.InputStreamReader.read(InputStreamReader.java:184)
	at java.io.BufferedReader.fill(BufferedReader.java:161)
	at java.io.BufferedReader.readLine(BufferedReader.java:324)
	at java.io.BufferedReader.readLine(BufferedReader.java:389)
	at com.test.Main.main(Main.java:41)

也可以不自動(dòng)鏈接

try (Socket socket = new Socket();
	Scanner sc = new Scanner(System.in)) {
		socket.connect(new InetSocketAddress("localhost", 8080), 1000);
	}

可能會(huì)出現(xiàn)連接雙方出現(xiàn)意外卻通知不到對(duì)方的情況,這個(gè)時(shí)候其中一方還持有聯(lián)系,就會(huì)占用資源,可以使用setKeepAlive()的方法來(lái)防止:

socket.setKeepAlive(true);

當(dāng)客戶端連接之后,如果此函數(shù)設(shè)置值為true,當(dāng)對(duì)方?jīng)]有發(fā)送任何數(shù)據(jù)過(guò)來(lái)的時(shí)候,超過(guò)一個(gè)時(shí)間(要看系統(tǒng)內(nèi)核參數(shù)配置),這邊就會(huì)發(fā)送一個(gè)ack探測(cè)包,探測(cè)TCP/IP連接是否有效

此緩沖區(qū)大小為:8192,我們可以手動(dòng)調(diào)整其大小來(lái)優(yōu)化傳輸效率:

socket.setReceiveBufferSize(25565);   //TCP接收緩沖區(qū)
socket.setSendBufferSize(25565);    //TCP發(fā)送緩沖區(qū)

使用Socket傳輸文件

實(shí)現(xiàn)文件傳輸

用戶端

public class Main {
    public static void main(String[] args) {
        try(Socket s = new Socket("localhost", 8080)){
            FileInputStream fis = new FileInputStream("test.txt"); //輸入文件
            OutputStream stream = s.getOutputStream(); //輸出流
            byte[] bytes = new byte[1024];
            int len;
            while((len = fis.read(bytes)) != -1) {
                stream.write(bytes, 0, len);
            }
            fis.close();
            stream.flush();
            stream.close();
            System.out.println("文件已傳輸");
        }catch(IOException e) {
            System.out.println("連接失敗");
            e.printStackTrace();
        }
    }
}

服務(wù)端

public class server {
    public static void main(String[] args) {
        try(ServerSocket server = new ServerSocket(8080)){
            Socket socket = server.accept();

           InputStream stream = socket.getInputStream();
           FileOutputStream file = new FileOutputStream("toserver.txt");
           byte[] buffer = new byte[1024];
            int len;
            while((len = stream.read(buffer)) != -1){
                file.write(buffer, 0, len);
            }
            file.flush();
            file.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

使用瀏覽器訪問(wèn)Socket服務(wù)器

public class server {
    public static void main(String[] args) {
        try(ServerSocket server = new ServerSocket(8080)){
            System.out.println("正在等待客戶端連接:");
            Socket socket = server.accept();
            System.out.println("IP地址為:" + socket.getInetAddress().getHostAddress());
            InputStream in = socket.getInputStream();
            while(true) {
                int read = in.read();
                if(read == -1) {
                    break;
                }
                System.out.print((char) read);
            }
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

啟動(dòng)Server端,用瀏覽器輸入http://localhost:8080或是http://127.0.0.1:8080/訪問(wèn);會(huì)發(fā)現(xiàn)瀏覽器無(wú)法訪問(wèn),但是IDEA給了一堆反饋

socket 發(fā)送文件,JavaWeb,tcp/ip,udp

我們的服務(wù)端能夠讀取HTTP請(qǐng)求。但是Http協(xié)議并不會(huì)保持長(zhǎng)連接,在得到我們響應(yīng)的數(shù)據(jù)后會(huì)立即關(guān)閉TCP連接。

既然使用的是Http連接,如果我們的服務(wù)器要支持響應(yīng)HTTP請(qǐng)求,那么就需要按照HTTP協(xié)議的規(guī)則,返回一個(gè)規(guī)范的響應(yīng)文本,首先是響應(yīng)頭,它至少要包含一個(gè)響應(yīng)碼:

HTTP/1.1 200 Accpeted

然后就是響應(yīng)內(nèi)容(注意一定要換行再寫),我們嘗試來(lái)編寫一下支持HTTP協(xié)議的響應(yīng)內(nèi)容:

public static void main(String[] args) {
    try(ServerSocket server = new ServerSocket(8080)){
        System.out.println("正在等待客戶端連接...");
        Socket socket = server.accept();
        System.out.println("客戶端已連接,IP地址為:"+socket.getInetAddress().getHostAddress());
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
        System.out.println("接收到客戶端數(shù)據(jù):");
        while (reader.ready()) System.out.println(reader.readLine()); 
        OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
        writer.write("HTTP/1.1 200 Accepted\r\n");   //200是響應(yīng)碼,Http協(xié)議規(guī)定200為接受請(qǐng)求,400為錯(cuò)誤的請(qǐng)求,404為找不到此資源(不止這些,還有很多)
        writer.write("\r\n");   //在請(qǐng)求頭寫完之后還要進(jìn)行一次換行,然后寫入響應(yīng)實(shí)體(會(huì)在瀏覽器上展示的內(nèi)容)
        writer.write("You're on your own Kids!");
        writer.flush();
    }catch (Exception e){
        e.printStackTrace();
    }
}

我們可以打開(kāi)瀏覽器的開(kāi)發(fā)者模式,我們來(lái)觀察一下瀏覽器的實(shí)際請(qǐng)求過(guò)程。
socket 發(fā)送文件,JavaWeb,tcp/ip,udp文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-724910.html

到了這里,關(guān)于使用Socket技術(shù)進(jìn)行數(shù)據(jù)傳輸、傳輸文件;瀏覽器訪問(wèn)Socket服務(wù)器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包