本文實例講解了Java Socket編程實現簡單的問候服務的詳細代碼,供大家參考,具體內容如下
服務器端:
實現一個最簡單的Hello服務,打印輸出客戶端IP地址到控制臺,對任何連接的客戶端都會發送一串字符(Hello, Java Socket)然后關閉與客戶端連接。等待下一個客戶端的連接請求到來。
客戶端:
實現一個最簡單的Socket連接到Hello服務器端,接受服務器端發送過來的字節數據打印并輸出內容到控制臺。
關鍵技巧:
由于JAVA中提供非常多的輸入與輸出流API,導致很多初學者接觸JAVA SOCKET編程時,由于對網絡字節通信的本質缺乏了解,直接一個readline()去接受Socket字節流。但是由于發送一方并沒有發送/r/n導致一直無法讀到數據,這個是最常見的一個錯誤。另外一些常見的錯誤包括沒有初始化接受緩沖區導致字符亂碼,沒有按照讀入接受到字節數重新組裝,導致接受到的數據異常。所以代碼演示了什么叫按字節發送與按字節接受,這個是網絡編程中非常重要的概念與原則。讓那些輸入流println()方法與輸出流readline()方法見鬼去吧,不是不好用,而是我建議你不要用,因為那些會妨礙你的網絡編程本質的認識與理解。另外我要特別說明一下:有時候flush()真的不是必須的除非你使用了帶有緩沖的輸入與輸出流來讀寫字節。
服務器端代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
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來實現服務器端啟動。
客戶端代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
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
程序運行結果:
以上就是本文的全部內容,希望對大家的學習有所幫助。