App下載

java 程序間如何進(jìn)行通信?詳解java socket編程

猿友 2021-06-23 14:59:47 瀏覽數(shù) (4271)
反饋

許多學(xué)習(xí)java SE的小伙伴可能會(huì)羨慕學(xué)java web的小伙伴——他們能進(jìn)行前后端交互,看著就很厲害的樣子。而學(xué)會(huì)json的小伙伴可能會(huì)嘗試使用類(lèi)似web的方法通過(guò)json來(lái)進(jìn)行數(shù)據(jù)傳輸。但實(shí)際上,java提供了一種更加高效的程序間傳輸數(shù)據(jù)的方式,這就是socket。接下來(lái)的文章,小編將用一個(gè)socket的實(shí)際項(xiàng)目,來(lái)讓各位小伙伴了解什么是socket網(wǎng)絡(luò)編程。

什么是socket?

socket,中文翻譯為套接字。它是一種對(duì)網(wǎng)絡(luò)中不同主機(jī)上的應(yīng)用進(jìn)程(或者相同主機(jī)的不同應(yīng)用進(jìn)程)之間進(jìn)行雙向通信的端點(diǎn)的抽象。實(shí)際上就是兩個(gè)網(wǎng)絡(luò)各種通信連接中的端點(diǎn)。它的作用就是完成應(yīng)用間的數(shù)據(jù)傳輸。

套接字技術(shù)簡(jiǎn)單的來(lái)講就是通過(guò)socket,將兩個(gè)應(yīng)用進(jìn)行連接,連接之后就能進(jìn)行數(shù)據(jù)傳輸了。socket只是實(shí)現(xiàn)連接的方法。 

小編認(rèn)為套接字這個(gè)翻譯并不能直接反映出這門(mén)技術(shù)的特點(diǎn)(過(guò)于生澀),socket可以被翻譯為插座,而實(shí)際上套接字技術(shù)更像是軟件上的“插座”和“插頭”。漢語(yǔ)中的套接,是一種水管對(duì)接的技術(shù),使用一個(gè)套接管將兩端的水管連接起來(lái),這種技術(shù)就叫套接,所以是不是能理解什么是套接字了呢?

更多關(guān)于socket協(xié)議的介紹,可以前往websocket協(xié)議進(jìn)行查看。

怎么使用socket?

不同語(yǔ)言實(shí)現(xiàn)套接字的方式不同,java有專(zhuān)門(mén)實(shí)現(xiàn)套接字的包。只需要?import? 相應(yīng)的包,就可以進(jìn)行套接字編程。

創(chuàng)建socket連接后可以通過(guò)?getInputStream()?和?getOutputStream()?的方法來(lái)獲取和發(fā)送socket之間傳輸?shù)臄?shù)據(jù)。

接下來(lái)就用一個(gè)實(shí)例代碼來(lái)介紹一下怎么使用socket吧!

socket項(xiàng)目實(shí)戰(zhàn)

server.java

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Server {
    public static void main(String[] args){
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            //在8888端口上監(jiān)聽(tīng),看是否有連接請(qǐng)求過(guò)來(lái)
            System.out.println("開(kāi)啟服務(wù)端");
            Socket accept = serverSocket.accept();
            //獲取socket連接
            System.out.println("有連接過(guò)來(lái)"+accept);
            Thread thread1 = new Thread(){//使用多線程來(lái)進(jìn)行收發(fā),線程1用來(lái)接收消息
                @Override
                public void run() {
                    try {
                        InputStream inputStream = accept.getInputStream();//獲取socket輸入流
                        DataInputStream dataInputStream = new DataInputStream(inputStream);
                        //把輸入流封裝在DataInputStream
                        while (true){
                            String msg = dataInputStream.readUTF();//使用readUTF讀取字符串
                            System.out.println("監(jiān)聽(tīng)客戶端消息: "+msg);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            Thread thread2 = new Thread(){//線程2用來(lái)發(fā)送消息
                @Override
                public void run() {
                    try {
                        OutputStream outputStream = accept.getOutputStream();
                        //打開(kāi)輸出流
                        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
                        //把輸出流封裝在DataOutputStream中
                        Scanner scanner = new Scanner(System.in);
                        while (true){
                            String strServer = scanner.next();
                            dataOutputStream.writeUTF(strServer);//使用writeUTF發(fā)送字符串
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread1.start();
            thread2.start();
            thread1.join();
            System.out.println("服務(wù)器關(guān)閉");
            accept.close();//關(guān)閉單個(gè)socket連接
            serverSocket.close(); //關(guān)閉這個(gè)socket 服務(wù)器
        } catch (Exception e) {
            System.out.println("斷開(kāi)連接");
        }
    }
}

client.java

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        String host = "127.0.0.1";//目標(biāo)電腦的ip地址,這里的地址是本機(jī)地址
        int port = 8888;//目標(biāo)電腦的端口
        boolean flag = true;
        try {
            Socket socket = new Socket(host, port);//創(chuàng)建目標(biāo)連接,傳入ip地址和端口號(hào)
            System.out.println("開(kāi)啟客戶端");
            Thread thread1 = new Thread() {//使用多線程方法來(lái)實(shí)行收發(fā),線程1負(fù)責(zé)接收信息
                @Override
                public void run() {
                    try {
                        InputStream inputStream = socket.getInputStream();//獲取socket輸入流
                        DataInputStream dataInputStream = new DataInputStream(inputStream);
                        //把輸入流封裝在DataInputStream
                        while (true) {
                            String msg = dataInputStream.readUTF();//使用readUTF讀取字符串
                            System.out.println("接收服務(wù)端消息: " + msg);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            Thread thread2 = new Thread() {//線程2用來(lái)發(fā)送消息
                @Override
                public void run() {
                    try {
                        OutputStream outputStream = socket.getOutputStream();
                        //打開(kāi)輸出流
                        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
                        //把輸出流封裝在DataOutputStream中
                        Scanner scanner = new Scanner(System.in);
                        while (true) {
                            String str = scanner.next();
                            dataOutputStream.writeUTF(str);//使用writeUTF發(fā)送字符串
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread1.start();
            thread2.start();
            thread1.join();
            System.out.println("客戶端關(guān)閉");
            socket.close();//關(guān)閉這個(gè)socket
        } catch (Exception e) {
            System.out.println("斷開(kāi)連接");
        }
    }
}

上述代碼涉及到多線程的知識(shí),如果對(duì)多線程有所疑問(wèn),可以前往java多線程編程進(jìn)行學(xué)習(xí)。如果理解不了socket代碼,也可以前往java網(wǎng)絡(luò)編程進(jìn)行學(xué)習(xí)。

小結(jié)

以上就是Java實(shí)現(xiàn)socket通信的方法。掌握socket通信對(duì)于java的多端開(kāi)發(fā)(比如服務(wù)器客戶端,或者兩個(gè)點(diǎn)對(duì)點(diǎn)應(yīng)用)是十分重要的,各位小伙伴一定要好好學(xué)習(xí)啊。


0 人點(diǎn)贊