Java通訊程序一例
本文介紹一種用Java的Socket和ServerSocket實現服務器和客戶機通訊的的方法。原理是在服務器端建立ServerSocket端口并監聽,接收到客戶端的連接請求時建立Socket,得到Socket的輸入輸出流。在客戶端新建Socket并獲得輸入輸出流。服務器和客戶端的輸入輸出流建立后使用writeLine()和println()方法彼此發送和接收數據。為提高代碼效率,建立兩個類clientAgent和serverAgent。
一、 客戶端圖形界面
本例中客戶端的圖形界面用Swing實現,服務器端不使用圖形界面
public class javaClient extends JFrame implements ActionListener//以JFrame為基類,實現ActionListener接口 { JButton sendButton; //"發送"按鈕 JTextField inputField; // 輸入框 JTextArea outputAera; // 服務器返回框 public javaClient() //在建構函數中完成圖形界面的初始化 { inputField=new JTextField("這里輸入..."); //供客戶端輸入的文本框 outputArea=new JTextArea("服務器返回"); //顯示服務器返回數據的文本域 sendButton=new JButton("發送"); JPanel panel=new JPanel(); //新建面板 panel.setLayout(new BorderLayout()); //設置面板風格為BorderLayout panel.add(inputField,BorderLayout.NORTH); //放置控件 panel.add(outputArea,BorderLayout.CENTER); setTitle("Java通訊客戶端"); setContentPane(panel); } } |
![]() |
二、 客戶端通訊類clientAgent
新建一個自定義包clientAgent,包含類clientAgent,該類用來執行和服務器端的交互,將界面和通訊類分開可以使程序的調試和維護更為容易。clientAgent類的作用包括:
1、在建構函數中建立和服務器的連接。
2、sendRequest()方法向服務器發送數據。
3、getResponse()方法從服務器端獲得回應
1、 成員變量
clientAgent類的成員變量包括: PrintStream ops; //輸出流(指向服務器) DataInputStream ips;//輸入流(來自服務器) String cltRequest;//客戶端請求 String svrResponse;//服務器端回應 |
2、 建構函數clientAgent(String serverName,int port)包含兩個參數,接收從javaClient的main()函數中傳遞來的服務器名稱和端口號
public clientAgent(String serverName,int port) { try { Socket clientSocket=new Socket(serverName,port ); //根據服務器名和端口號建立Socket ops=new PrintStream(clientSocket.getOutputStream());//獲得Socket的輸出流 ips=new DataInputStream(clientSocket.getInputStream());//獲得Socket的輸入流 } catch(Exception e) { System.out.println("無法連接服務器!"); } } |
3、 sendRequest()方法
public void sendRequest(String request) { ops.println(request); //向Socket的輸出流寫入字符串 } 4、 getRespone()方法 public String getResponse() { String str=new String(); try { str=ips.readLine(); //從Socket的輸入流讀入字符串 } catch(IOException e){} //必須捕獲錯誤 return str; } |
三、 客戶端javaClient類的main()函數和事件處理
1、 main()函數
有了上面的鋪墊,main()函數變得非常簡潔
public static void main(String[] args) { javaClient frame=new javaClient(); frame.pack();//注意javaClient是JFrame的派生類,調用基類方法 frame.setVisible(true); ca=new clientAgent("127.0.0.1",1001); //傳遞服務器名稱和端口號 } |
2、 捕獲并處理單擊"發送"按鈕的事件
public void actionPerformed(ActionEvent e) { if(e.getSource()==sendButton) //判斷事件源控件是否是"發送"按鈕 { ca.sendRequest(inputField.getText()); //發送文本框中的文本 outputArea.append(""+ca.getResponse()); //接收服務器回應并寫入文本域 } } |
四、 服務器端
1、 serverAgent類
1) 成員變量
ServerSocket svrSkt=null; Socket cltSkt=null; DataInputStream input=null; //輸入流,來自客戶端 PrintStream output=null; //輸出流,指向客戶端 |
2) serverAgent()建構函數
public serverAgent(int port) //main()函數傳遞監聽端口號 { System.out.println("服務器代理正在監聽,端口:"+port); try { svrSkt=new ServerSocket(port); //開始監聽 }catch(IOException e){System.out.println("監聽端口"+port+"失敗");} try { cltSkt=svrSkt.accept(); //接收連接請求 } catch(IOException e){System.out.println("連接失敗");} try { input=new DataInputStream(cltSkt.getInputStream()); //獲得輸入流 output=new PrintStream(cltSkt.getOutputStream()); //獲得輸出流 } catch(IOException e){} output.println("歡迎......"); } 3) getRequest()方法讀取客戶端發送的數據 public String getRequest() { String frmClt=null; try { frmClt=input.readLine(); } catch(Exception e){ System.out.println("無法讀取端口....."); System.exit(0); } return frmClt; } |
4) sendResponse()方法向客戶端發送數據
public void sendResponse(String response) { try { output.println(response); } catch(Exception e){ System.out.println("寫端口失敗......"); System.exit(0); } } |
2、main()函數
在main()函數中對客戶端發送的不同請求進行不同的處理,本例只是介紹原理,因此服務器端只是簡單地將客戶端發送來的數據發送回去:
public static void main(String[] args) throws IOException { serverAgent sa=new serverAgent(1001); while(true) { sa.sendResponse(sa.getRequest()); } } |