1. 程式人生 > >java網絡編程實現兩端聊天

java網絡編程實現兩端聊天

system.in 客戶端和服務器 發送 效率 pri err avi 短信 ktr

網絡編程的三要素:

  1. ip地址:唯一標識網絡上的每一臺計算機
  2. 端口號:計算機中應用的標號(代表一個應用程序),0-1024系統使用或者保留端口,有效端口0-65535(short)
  3. 通信協議:通信的規則 TCP UDP

UDP:相當於發短信,不需要建立連接,數據包的大小限制在64k內,效率高,不安全,容易丟包

TCP:相當於打電話,需要建立連接,效率相對較低,數據傳輸安全,三次握手完成。


下面使用TCP進行網絡通信:
服務端:

 1 public static void main(String[] args) throws Exception {
 2         //
創建服務端的對象 3 ServerSocket ss = new ServerSocket(8000); 4 //等待客戶端的接入 5 Socket client = ss.accept(); 6 //從輸入流中得到數據 7 InputStream is = client.getInputStream(); 8 byte[] by = new byte[1024]; 9 int len = is.read(by); 10 String str = new String(by,0,len);
11 System.out.println(str); 12 //關閉 13 client.shutdownInput(); 14 is.close(); 15 client.close(); 16 17 }

客戶端:

 1 public static void main(String[] args) throws Exception {
 2         //創建客戶端套接字對象,給定ip地址
 3         Socket client = new Socket("192.168.6.166",8000);
4 //獲取客戶端的輸出流 5 OutputStream os = client.getOutputStream(); 6 //向輸出流中寫入數據 7 os.write("在?".getBytes()); 8 os.flush(); 9 //切斷輸出流 10 client.shutdownOutput(); 11 //關閉流對象,關閉套接字 12 is.close(); 13 os.close(); 14 client.close(); 15 16 }

通過上面的代碼能夠實現基本的發送信息,和接收信息。不過只能客戶端發送信息,服務器被動接收信息,下面來實現客戶端和服務器互相發送信息:

服務器端:

 1 public static void main(String[] args) throws IOException {
 2         ServerSocket ss = new ServerSocket(8000);
 3         Scanner sc = new Scanner(System.in);
 4         System.out.println("服務器啟動!");
 5         Socket s = ss.accept();
 6         OutputStream os = s.getOutputStream();
 7         InputStream is = s.getInputStream();
 8         boolean bool = true;
 9         while(bool){
10             //服務器接收信息
11             byte[] bt = new byte[1024];
12             int length = is.read(bt);
13             System.out.println("\t\t\t"+new String(bt,0,length)+":客戶端");
14             //服務器發送信息
15             System.out.println("服務器:");
16             os.write(sc.next().getBytes());
17             os.flush();
18         }
19         s.shutdownInput();
20         is.close();
21         os.close();
22         s.close();
23         ss.close();
24 
25     }

客戶端:

 1 public static void main(String[] args) throws UnknownHostException, IOException {
 2         System.out.println("客戶端啟動");
 3         Socket client = new Socket("127.0.0.1",8000);
 4         Scanner sc = new Scanner(System.in);
 5         boolean bool = true;
 6         OutputStream os = client.getOutputStream();
 7         InputStream is = client.getInputStream();
 8         while(bool){
 9             //客戶端發送信息
10             System.out.println("客戶端:");
11             String str = sc.next();
12             os.write(str.getBytes());
13             os.flush();
14             //客戶端接收信息
15             byte[] by = new byte[1024];
16             int index = is.read(by);
17             System.out.println("\t\t\t"+new String(by,0,index)+":服務器");
18         }
19         client.shutdownOutput();
20         os.close();
21         is.close();
22         sc.close();
23         client.close();
24     }

使用上面的方式進行通信,實現結果:
客戶端:

技術分享

服務器:
技術分享


這樣實現了兩端相互通信的要求,如果一方連續發送兩條信息的時候,這個程序就會開始出現問題。於是使用線程解決這個問題,具體如下:

客戶端:

 1 public class servletSockettest {
 2     public static void main(String[] args) throws IOException {
 3         ServerSocket ss = new ServerSocket(8888);
 4         System.out.println("服務器啟動!");
 5         final Socket s = ss.accept();
 6         boolean b = true;
 7         InputStream is = s.getInputStream();
 8         //服務器把輸入放入線程裏面執行,不會影響主線程的接收信息功能
 9         Thread t = new Thread(){
10             OutputStream os = s.getOutputStream();
11             Scanner sc  = new Scanner(System.in);
12             @Override
13             public void run() {
14                 // TODO Auto-generated method stub
15                 boolean b = true;
16                 while(b){
17                     try {
18                         System.out.print("服務器輸入:");
19                         os.write(sc.next().getBytes());
20                         os.flush();
21                     } catch (IOException e) {
22                         // TODO Auto-generated catch block
23                         e.printStackTrace();
24                     }
25                 }
26             }
27         };
28         t.start();
29         while(b){
30             byte[] bt = new byte[1024];
31             int length = is.read(bt);
32             String str = new String(bt,0,length);
33             System.out.println("\t\t\t"+str+":客戶端");
34         }
35 
36 
37         is.close();
38         s.shutdownInput();
39         s.close();
40         ss.close();
41 
42     }
43 }

客戶端:

 1 public class Sockettest {
 2     public static void main(String[] args) throws UnknownHostException, IOException {
 3         final Socket client = new Socket("192.168.6.166",8888);
 4         Scanner sc = new Scanner(System.in);
 5         System.out.println("客戶端啟動");
 6         OutputStream os = client.getOutputStream();
 7         //新建一個線程用來接收信息,不影響主線程的輸入發送信息。
 8         Thread t = new Thread(){
 9             InputStream is = client.getInputStream();
10             @Override
11             public void run() {
12                 // TODO Auto-generated method stub
13                 boolean b = true;
14                 while(b){
15                     try {
16                         byte[] bt = new byte[1024];
17                         int length = is.read(bt);
18                         String str = new String(bt,0,length);
19                         System.out.println("\t\t\t"+str+":服務器");
20                     } catch (IOException e) {
21                         // TODO Auto-generated catch block
22                         e.printStackTrace();
23                     }
24                 }
25             }
26         };
27         t.start();
28         boolean b = true;
29         while(b){
30             System.out.print("客戶端輸入:");
31             os.write(sc.next().getBytes());
32             os.flush();
33         }
34         os.close();
35         client.shutdownOutput();
36         client.close();
37     }
38 }

運行結果:
客戶端
技術分享
服務器:
技術分享

這樣就可以實現基本上的通信了。如果有興趣,可以結合JFrame窗體,實現多個窗口相互聊天,不再使界面這麽難看。

java網絡編程實現兩端聊天