本文執行個體講解了Java Socket編程實現簡單的問候服務的詳細代碼,供大家參考,具體內容如下
伺服器端:
實現一個最簡單的Hello服務,列印輸出用戶端IP地址到控制台,對任何串連的用戶端都會發送一串字元(Hello, Java Socket)然後關閉與用戶端串連。等待下一個用戶端的串連請求到來。
用戶端:
實現一個最簡單的Socket串連到Hello伺服器端,接受伺服器端發送過來的位元組資料列印並輸出內容到控制台。
關鍵技巧:
由於JAVA中提供非常多的輸入與輸出資料流API,導致很多初學者接觸JAVA SOCKET編程時,由於對網路位元組通訊的本質缺乏瞭解,直接一個readline()去接受Socket位元組流。但是由於發送一方並沒有發送/r/n導致一直無法讀到資料,這個是最常見的一個錯誤。另外一些常見的錯誤包括沒有初始化接受緩衝區導致字元亂碼,沒有按照讀入接受到位元組數重新組裝,導致接受到的資料異常。所以代碼示範了什麼叫按位元組發送與按位元組接受,這個是網路編程中非常重要的概念與原則。讓那些輸入資料流println()方法與輸出資料流readline()方法見鬼去吧,不是不好用,而是我建議你不要用,因為那些會妨礙你的網路編程本質的認識與理解。另外我要特別說明一下:有時候flush()真的不是必須的除非你使用了帶有緩衝的輸入與輸出資料流來讀寫位元組。
伺服器端代碼:
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監聽並等待串連,使用Java Thread來實現伺服器端啟動。
用戶端代碼如下:
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個用戶端去串連伺服器端,接受到伺服器端問候以後用戶端關閉串連。
特別提示:一定要初始化緩衝區charBuff
程式運行結果:
以上就是本文的全部內容,希望對大家的學習有所協助。