java網絡編程實現兩端聊天
阿新 • • 發佈:2017-08-11
system.in 客戶端和服務器 發送 效率 pri err avi 短信 ktr
網絡編程的三要素:
- ip地址:唯一標識網絡上的每一臺計算機
- 端口號:計算機中應用的標號(代表一個應用程序),0-1024系統使用或者保留端口,有效端口0-65535(short)
- 通信協議:通信的規則 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網絡編程實現兩端聊天