Java Socket編程實現(xiàn)簡單的問候服務
本文實例講解了Java Socket編程實現(xiàn)簡單的問候服務的詳細代碼,供大家參考,具體內容如下
服務器端:
實現(xiàn)一個最簡單的Hello服務,打印輸出客戶端IP地址到控制臺,對任何連接的客戶端都會發(fā)送一串字符(Hello, Java Socket)然后關閉與客戶端連接。等待下一個客戶端的連接請求到來。
客戶端:
實現(xiàn)一個最簡單的Socket連接到Hello服務器端,接受服務器端發(fā)送過來的字節(jié)數(shù)據(jù)打印并輸出內容到控制臺。
關鍵技巧:
由于JAVA中提供非常多的輸入與輸出流API,導致很多初學者接觸JAVA SOCKET編程時,由于對網(wǎng)絡字節(jié)通信的本質缺乏了解,直接一個readline()去接受Socket字節(jié)流。但是由于發(fā)送一方并沒有發(fā)送/r/n導致一直無法讀到數(shù)據(jù),這個是最常見的一個錯誤。另外一些常見的錯誤包括沒有初始化接受緩沖區(qū)導致字符亂碼,沒有按照讀入接受到字節(jié)數(shù)重新組裝,導致接受到的數(shù)據(jù)異常。所以代碼演示了什么叫按字節(jié)發(fā)送與按字節(jié)接受,這個是網(wǎng)絡編程中非常重要的概念與原則。讓那些輸入流println()方法與輸出流readline()方法見鬼去吧,不是不好用,而是我建議你不要用,因為那些會妨礙你的網(wǎng)絡編程本質的認識與理解。另外我要特別說明一下:有時候flush()真的不是必須的除非你使用了帶有緩沖的輸入與輸出流來讀寫字節(jié)。
服務器端代碼:
package com.gloomyfish.socket.tutorial.two; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class HelloService extends Thread { private ServerSocket serverSocket; public HelloService(int port) throws IOException { serverSocket = new ServerSocket(port); } public void run() { try { while(true) { System.out.println("Waiting for client on port " + serverSocket.getLocalPort()); Socket client = serverSocket.accept(); // blocked & waiting for income socket System.out.println("Just connected to " + client.getRemoteSocketAddress()); DataOutputStream dos = new DataOutputStream(client.getOutputStream()); byte[] hello = "Hello, Java Socket".getBytes(); dos.write(hello, 0, hello.length); dos.close(); client.close(); } } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { try { HelloService service = new HelloService(9999); service.start(); } catch (IOException e) { e.printStackTrace(); } } }
服務器在端口9999監(jiān)聽并等待連接,使用Java Thread來實現(xiàn)服務器端啟動。
客戶端代碼如下:
package com.gloomyfish.socket.tutorial.two; import java.io.DataInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; public class HelloClient { private int clientNumber; private SocketAddress address; public HelloClient(int clientNum) { clientNumber = clientNum; } public void setupClients(String serverHostName, int port) throws IOException { address = new InetSocketAddress(serverHostName, port); for(int i=0; i<clientNumber; i++) { System.out.println(); System.out.println("start client No. " + (i+1)); Socket socket = new Socket(); socket.connect(address); DataInputStream bufferedReader = new DataInputStream(socket.getInputStream()); byte[] cbuff = new byte[256]; char[] charBuff = new char[256]; int size = 0; while( (size = bufferedReader.read(cbuff))> 0) { convertByteToChar(cbuff, charBuff, size); System.out.println(charBuff); } bufferedReader.close(); socket.close(); } } private void convertByteToChar(byte[] cbuff, char[] charBuff, int size) { for(int i=0; i<charBuff.length; i++) { if(i < size) { charBuff[i] = (char)cbuff[i]; } else { charBuff[i] = ' '; } } } public static void main(String[] args) { try { HelloClient client = new HelloClient(10); client.setupClients("localhost", 9999); } catch (IOException e) { e.printStackTrace(); } } }
啟動10個客戶端去連接服務器端,接受到服務器端問候以后客戶端關閉連接。
特別提示:一定要初始化緩沖區(qū)charBuff
程序運行結果:
以上就是本文的全部內容,希望對大家的學習有所幫助。
相關文章
springboot使用redis對單個對象進行自動緩存更新刪除的實現(xiàn)
本文主要介紹了springboot使用redis對單個對象進行自動緩存更新刪除的實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08Java網(wǎng)絡通信中ServerSocket的設計優(yōu)化方案
今天小編就為大家分享一篇關于Java網(wǎng)絡通信中ServerSocket的設計優(yōu)化方案,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-04-04詳解Spring Security的Web應用和指紋登錄實踐
這篇文章主要介紹了詳解Spring Security的Web應用和指紋登錄實踐,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-03-03SpringMvc向request域中設置數(shù)據(jù)的方法
這篇文章主要介紹了SpringMvc向request域中設置數(shù)據(jù)的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09