如何使用Java完成Socket通信
使用Java完成Socket通信
用Java實(shí)現(xiàn)一個(gè)最基本的Socket_TCP編程
可以放在一個(gè)項(xiàng)目中,創(chuàng)建兩個(gè)Java文件
注意:
- 先運(yùn)行服務(wù)器端(SocketTCP_Server類)
- 再運(yùn)行客戶端(SocketTCP_Client類)
import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; /** 服務(wù)器端 */ public class SocketTCP_Server { public static void main(String[] args) throws Exception { //思路 //1. 在本機(jī) 的9999端口監(jiān)聽(tīng), 等待連接 // 細(xì)節(jié): 要求在本機(jī)沒(méi)有其它服務(wù)在監(jiān)聽(tīng)9999 // 細(xì)節(jié):這個(gè) ServerSocket 可以通過(guò) accept() 返回多個(gè)Socket[多個(gè)客戶端連接服務(wù)器的并發(fā)] ServerSocket serverSocket = new ServerSocket(9999); System.out.println("服務(wù)器段,監(jiān)聽(tīng)9999端口,等待連接"); //2. 當(dāng)沒(méi)有客戶端連接9999端口時(shí),程序會(huì) 阻塞, 等待連接 // 如果有客戶端連接,則會(huì)返回Socket對(duì)象,程序繼續(xù) Socket socket = serverSocket.accept(); System.out.println("服務(wù)器端 socket = " + socket.getClass()); //3. 通過(guò)socket.getInputStream() 讀取客戶端寫(xiě)入到數(shù)據(jù)通道的數(shù)據(jù), 顯示 InputStream inputStream = socket.getInputStream(); //4. IO讀取 byte[] buf = new byte[1024]; int readLine = 0; while ((readLine = inputStream.read(buf)) != -1) { System.out.println(new String(buf, 0, readLine)); } //5.關(guān)閉IO流和socket inputStream.close(); socket.close(); serverSocket.close(); } }
import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; /** * 客戶端 */ public class SocketTCP_Client { public static void main(String[] args) throws Exception { //1. 連接服務(wù)端 (ip , 端口) //解讀:連接本機(jī)的 9999端口, 如果連接成功,返回Socket對(duì)象 Socket socket = new Socket(InetAddress.getLocalHost(), 9999); System.out.println("客戶端 socket = " + socket.getClass()); //2. 連接上后,生成Socket, 通過(guò)socket.getOutputStream() //得到和 socket對(duì)象關(guān)聯(lián)的輸出流對(duì)象 OutputStream outputStream = socket.getOutputStream(); //3. 通過(guò)輸出流,寫(xiě)入數(shù)據(jù)到 數(shù)據(jù)通道 outputStream.write("Hello,server".getBytes()); //4. 關(guān)閉流對(duì)象和socket, 必須關(guān)閉 outputStream.close(); socket.close(); System.out.println("客戶端退出..."); } }
Java socket通信,用于各種無(wú)線網(wǎng)絡(luò)通信
無(wú)論是使用Wi-Fi模塊在單片機(jī)和電腦或手機(jī)之間進(jìn)行數(shù)據(jù)傳輸,基本方法都是:
一臺(tái)設(shè)備建立服務(wù)端,一臺(tái)設(shè)備作為客戶端連接,連接成功后即可進(jìn)行通信。
服務(wù)端的建立
Java中建立服務(wù)端,不局限于電腦才能建立,一臺(tái)手機(jī)同樣可以建立:
/** * 建立服務(wù)端 * * @param sp 建立服務(wù)端的通信端口 */ private static void StartServer(int sp) { try { serverSocket = new ServerSocket(sp); //服務(wù)端使用ServerSocket建立 System.out.println("Server started at:" + InetAddress.getLocalHost()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } new Thread(){ @Override public void run() { while (SERVER_ENABLE) { //循環(huán)監(jiān)聽(tīng) try { s = serverSocket.accept(); //在有客戶端連入之前,while循環(huán)將一直卡在這里 new MasterServerThread(s).start(); //客戶端連接成功后,開(kāi)啟一個(gè)自定義的服務(wù)器線程 } catch (IOException e) { e.printStackTrace(); } } } }.start(); }
服務(wù)線程
/** * 服務(wù)器主線程 */ private static class MasterServerThread extends Thread { Socket masterSocket = null; //傳入的客戶端Socket String socketKind = null; //構(gòu)造方法,在實(shí)例化本Class時(shí)要求傳入客戶端的socket public MasterServerThread(Socket s) { this.masterSocket = s; } @Override public void run() { BufferedReader bre = null; try { bre = new BufferedReader(new InputStreamReader(masterSocket.getInputStream(), "utf-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { while ((socketKind = bre.readLine()) != null) { //接收讀取傳輸過(guò)來(lái)的數(shù)據(jù) //根據(jù)發(fā)過(guò)來(lái)的數(shù)據(jù)是什么,決定進(jìn)行指定操作 if (socketKind.contains(LOGIN_REQUEST)) {//TODO 處理登陸請(qǐng)求操作 //...... } else if (socketKind.contains(OPERATION_OF_BINDING_DEVICE)) {//TODO 處理設(shè)備綁定 //...... } } } catch (Exception e) { //e.printStackTrace(); } } }
客戶端的連接
/** * SERVER_IP : String型 * SERVER_PORT :int型 */ Socket socket = new Socket(SERVER_IP, SERVER_PORT); //服務(wù)端用的ServerSocket,客戶端對(duì)應(yīng)的是使用Socket ClientThread ct = new ClientThread(socket); //同樣開(kāi)啟客戶端線程,與服務(wù)器通信用 ct.start();
客戶端線程
/** * Class : ClientThread * 與服務(wù)端線程class十分相像 */ private class ClientThread extends Thread { Socket cSocket; BufferedReader br; public ClientThread(Socket s) { this.cSocket = s; } @Override public void run() { try { br = new BufferedReader(new InputStreamReader(cSocket.getInputStream(), "UTF-8")); while ((temp = br.readLine()) != null) { //Do Something... } }catch(IOException e){ e.printStackTrace(); } } }
發(fā)送消息
/** * 發(fā)送登陸信息 * @param id 用戶ID * @param pwd 賬號(hào)密碼 */ private void sendLoginMsg(final String id, final String pwd) { new Thread() { @Override public void run() { try { PrintWriter printWriter = new PrintWriter(socket.getOutputStream()); printWriter.println(LOGIN_REQUEST + "CONNECTION_FROM_APP" + "_" + id + "$" + pwd + "&"); printWriter.flush(); } catch (IOException e) { e.printStackTrace(); } } }.start(); }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
一文詳解Elasticsearch和MySQL之間的數(shù)據(jù)同步問(wèn)題
Elasticsearch中的數(shù)據(jù)是來(lái)自于Mysql數(shù)據(jù)庫(kù)的,因此當(dāng)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行增刪改后,Elasticsearch中的數(shù)據(jù),索引也必須跟著做出改變。本文主要來(lái)和大家探討一下Elasticsearch和MySQL之間的數(shù)據(jù)同步問(wèn)題,感興趣的可以了解一下2023-04-04SpringBoot深入刨析數(shù)據(jù)層技術(shù)
這篇文章主要介紹了SpringBoot數(shù)據(jù)層技術(shù)的解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08springboot中使用@NotNull注解無(wú)效解決方法
這篇文章主要給大家介紹了關(guān)于springboot中使用@NotNull注解無(wú)效的解決方法,進(jìn)行參數(shù)校驗(yàn)的時(shí)候,加了@NotNull注解,@Validated注解和@Valid注解,但是參數(shù)校驗(yàn)的時(shí)候不生效,需要的朋友可以參考下2023-08-08Spring Boot 啟動(dòng)注解過(guò)程分析
這篇文章主要為大家介紹了Spring Boot 啟動(dòng)注解過(guò)程示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06