Java中Socket通信-服務端和客戶端雙向傳輸字符串實現


場景

什么是socket

在計算機通信領域,socket 被翻譯為“套接字”,它是計算機之間進行通信的一種約定或一種方式。通過 socket 這種約定,一台計算機可以接收其他計算機的數據,也可以向其他計算機發送數據。

socket 的典型應用就是 Web 服務器和瀏覽器:瀏覽器獲取用戶輸入的 URL,向服務器發起請求,服務器分析接收到的 URL,將對應的網頁內容返回給瀏覽器,瀏覽器再經過解析和渲染,就將文字、圖片、視頻等元素呈現給用戶。

那么在Java中怎樣使用import java.net.Socket;來構建服務端和客戶端並進行通信傳輸字符串?

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi
關注公眾號
霸道的程序猿
獲取編程相關電子書、教程推送與免費下載。

實現

ServerSocket類能創建Socket(套接字)的服務端,Socket類能創建Socket的客戶端。

在代碼層面使用的方式就是使用Socket類去連接ServerSocket類,也就是客戶端要主動連接服務端。

ServerSocket類中的public Socket accept()方法的作用是偵聽並接受此套接字的連接。此方法在連接傳人之前一直阻塞。public Socket accept()方法的返回值是Socket類型。

那么什么時候不阻塞呢?有客戶端連接到服務端時就不再出現阻塞了,服務端的程序會繼續運行。

除了ServerSocket類中的accept()方法具有阻塞特性外,InputStream類中的read()方法也同樣具有阻塞特性。

通過使用Socket類的getlnputStream()方法可以獲得輸人流,從輸人流中獲取從對方發送過來的數據

客戶端向服務端發送字符串數據

首先新建一個Java項目SocketServer作為服務端

然后編寫其main方法,在main方法中調用接收並讀取字符串的方法

package com.badao;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Main {

    public static void main(String[] args) {

        //接受並讀取客戶端發送的字符串
        getStringFromClient();

    }

    //接受並讀取客戶端發送的字符串
    public static  void getStringFromClient()
    {
        try {
            char[] charArray = new char[10];
            //創建Socket服務端,開放端口8088
            ServerSocket serverSocket = new ServerSocket(8088);
            System.out.println("accept begin = " + System.currentTimeMillis());
            //調用accept方法,此時會堵塞
            Socket socket = serverSocket.accept();
            System.out.println("accept end =" + System.currentTimeMillis());
            //獲取客戶端發送的數據的輸入流
            InputStream inputStream = socket.getInputStream();
            //讀取輸入流
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            System.out.println("read begin =" + System.currentTimeMillis());
            int readLength = inputStreamReader.read(charArray);
            while (readLength != -1) {
                String newString = new String(charArray, 0, readLength);
                System.out.println(newString);
                readLength = inputStreamReader.read(charArray);
            }
            System.out.println("read end =" + System.currentTimeMillis());
            inputStreamReader.close();
            inputStream.close();
            socket.close();
            serverSocket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

然后在新建一個Java項目SocketClient作為客戶端,同樣新建一個main方法,並在main方法中調用發送字符串數據

到服務端的方法

package com.badao;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Main {

    public static void main(String[] args) throws IOException, InterruptedException {

    //客戶端向服務端發送字符串
    sendStringToServer();

    }

    //客戶端向服務端發送字符串
    public static void sendStringToServer() throws IOException, InterruptedException {
        System.out.println("socket begin ="+System.currentTimeMillis());
        //新建客戶端並請求服務端的ip為localhost 端口為8088
        Socket socket = new Socket("localhost",8088);
        System.out.println("socket end ="+System.currentTimeMillis());
        //休眠3秒
        Thread.sleep(3000);
        //獲取客戶端的輸出流 即向服務端發送的數據
        OutputStream outputStream = socket.getOutputStream();
        //向輸出流中寫入要發送的字符串數據
        outputStream.write("公眾號:霸道的程序猿".getBytes());
        outputStream.close();
        socket.close();
    }
}

然后運行服務端的main方法

 

 

此時服務端會一直堵塞在accept方法這里,一直等待客戶端發送數據。

然后運行客戶端的main方法,實現客戶端向服務端發動字符串數據,此時服務端接收到客戶端的字符串數據

 

 

服務端向客戶端發送數據

在服務端的項目中新建向客戶端發送字符串數據的方法

    //服務端向客戶端發送字符串數據
    public static void sendStringToClient() throws IOException {
        //新建Socket 服務端 並開放8088 端口
        ServerSocket serverSocket = new ServerSocket(8088);
        System.out.println("server堵塞開始 =" + System.currentTimeMillis());
        //獲取socket
        Socket socket = serverSocket.accept();
        System.out.println("server堵塞結束 ="+System.currentTimeMillis());
        //socket發送數據
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("來自服務端-公眾號:霸道的程序猿".getBytes());
        outputStream.close();
        socket.close();
        serverSocket.close();
    }

然后在main方法中取消運行上面的方法,改為運行此方法

    public static void main(String[] args) throws IOException {

        //接受並讀取客戶端發送的字符串
        //getStringFromClient();
        //服務端向客戶端發送字符串數據
        sendStringToClient();

    }

然后再客戶端項目中新建接受服務端數據的方法

 

   //客戶端接收來自服務端的數據
    public  static void getStringFromServer() throws IOException {
        System.out.println("client連接准備就緒 =" + System.currentTimeMillis());
        Socket socket = new Socket("localhost",8088);
        System.out.println("client連接成功結束 ="+System.currentTimeMillis());
        char[] charArray = new char[10];
        //獲取客戶端發送的數據的輸入流
        InputStream inputStream = socket.getInputStream();
        //讀取輸入流
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        System.out.println("read begin =" + System.currentTimeMillis());
        int readLength = inputStreamReader.read(charArray);
        while (readLength != -1) {
            String newString = new String(charArray, 0, readLength);
            System.out.println(newString);
            readLength = inputStreamReader.read(charArray);
        }
        System.out.println("read end =" + System.currentTimeMillis());
        inputStreamReader.close();
        inputStream.close();
        socket.close();
    }

然后在main方法中取消運行上面的方法,改為運行此方法。

首先運行服務端的main方法

 

 

此時服務端會堵塞,直接運行客戶端的main方法啟動客戶端之后

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM