場景
什么是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方法啟動客戶端之后