本文將給出完整 Socket 通信代碼,在 eclipse 中親測有效。在Android Studio中用Java開發也是一樣的,只是把代碼和控件搭配一下,註冊監聽就好。 |
網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱爲一個socket。
建立網絡通信連接至少要一對端口號(socket)。socket 本質是編程接口(API),對TCP/IP的封裝,TCP/IP也要提供可供程序員做網絡開發所用的接口,這就是Socket編程接口;HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發動機,提供了網絡通信的能力。
下載eclipse:
https://www.eclipse.org/
本文將給出完整 Socket 通信代碼,在 eclipse 中親測有效。在Android Studio中用Java開發也是一樣的,只是把代碼和控件搭配一下,註冊監聽就好。區別就是在 AS 中 import 的聲明不太一樣,然後窗口不需要自己建立。
效果如圖:
在eclipse中,File→New→Java Project→起個英文名字→Finish(我起的名字是TCP)
目錄結構:
新建完以後有個src默認包,右鍵 src→New→Package→ 輸入 com.net(因爲程序裏我用的包的名字是這個,你可以同時兩個一起改)→ Finish
然後右鍵 com.net → New → Class → 輸入 TCPClient(因爲我程序裏面用的這個類名稱)
然後右鍵 com.net → New → Class → 輸入 TCPServer(因爲我程序裏面用的這個類名稱)
兩個裏面分別粘貼代碼:
package com.net; import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; public class TCPServer { static DataInputStream dis=null; public static void main(String[] args){ boolean started=false; Socket s=null; TextArea ta=new TextArea(); ta.append("從客戶端接受的數據:"+"\n"); ServerSocket ss=null; try{ ss=new ServerSocket(8866); //端口號 }catch(BindException e){ System.exit(0); }catch(IOException e){ e.printStackTrace(); } Frame f=new Frame("服務器端"); //窗體名稱 f.setLocation(300, 300); //窗體出現位置 f.setSize(200, 200); //窗體大小 f.add(ta,BorderLayout.NORTH); f.pack(); f.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); f.setVisible(true); try{ //try-catch塊捕捉異常 started=true; while(started){ boolean bConnected=false; s=ss.accept(); bConnected=true; dis=new DataInputStream(s.getInputStream()); while(bConnected){ String str=dis.readUTF(); ta.append(str+"\n"); } } }catch(EOFException e){ System.out.println("Client closed!"); }catch(IOException e){ e.printStackTrace(); }finally{ try{ if(dis!=null) dis.close(); if(s!=null) s.close(); }catch(Exception e){ e.printStackTrace(); } } } }
package com.net; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class TCPClient extends Frame{ Socket s=null; DataOutputStream dos=null; DataInputStream dis=null; TextField tf=new TextField(40); List list=new List(6); public static void main(String[] args){ TCPClient client=new TCPClient(); client.list.add("向服務器端發送的數據:"); client.setTitle("客戶端"); client.run(); } public void run(){ setLocation(400,300); this.setSize(300, 300); add(tf,BorderLayout.SOUTH); add(list,BorderLayout.NORTH); pack(); this.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ disconnect(); System.exit(0); } }); tf.addActionListener(new MyListener()); setVisible(true); connect(); } public void connect(){ try{ s=new Socket("127.0.0.1",8866); dos=new DataOutputStream(s.getOutputStream()); }catch(UnknownHostException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } } public void disconnect(){ try{ dos.close(); s.close(); }catch(IOException e){ e.printStackTrace(); } } private class MyListener implements ActionListener{ public void actionPerformed(ActionEvent e){ String s1=null; String s2=null; String str=tf.getText().trim(); list.add(str); tf.setText(""); try{ dos.writeUTF(str); dos.flush(); }catch(IOException e1){ e1.printStackTrace(); } } } }
然後先運行服務器,再運行客戶端,否則會報錯,因爲Socket通信本質是先打開服務器監聽端口。然後就會出現效果圖。
本機迴環 IP 是 127.0.0.1,你可以改爲其他 IP 地址,即可實現跨機 Socket 通信。