Java網絡編程:服務器端和客戶端互發信息


引言

   

為了學習Java網絡編程,用一個QQ(屌絲版)作為例子練手,記錄屌絲版QQ的開發過程,這里我們認為已經掌握其中的網絡基礎部分,即HTTP協議,TCP/IP協議等,在此基礎上我們開始我們的Java網絡部分的學習,我們要知道服務器和客戶端是如何通信的,首先我們要了解Java網絡知識中的一個很重要的東西——Socket

   

Socket初探

   

ServerSocketSocket

   

首先服務器端需要用到java.net包下的ServerSocket類,該類的一個實例用於監聽等待客戶端的連接,而客戶端需要用到net包下的Socket類,用於向服務器端發送連接請求,客戶端是怎樣與服務器端建立連接的呢,首先客戶端的Socket實例要制定服務器端的ip地址和端口,服務器端如何與客戶端建立連接呢,服務器端的ServerSocket類的accept一直在監聽等待客戶端發來的連接請求,如果沒有收到,則一直阻塞在accept這句代碼這兒(可以在Socket s=ss.accept();這行代碼后面打印出一句語句,可以發現,程序並不會執行到這行代碼),以下代碼1說明服務器端ServerSocket的用法,代碼2說明客戶端Socket的用法

   

代碼1

   

創建一個類,名字叫Server,在類的構造函數中創建ServerSocket等實例

   

public class MyServer1 {

public MyServer1()

{

//9999號端口監聽

ServerSocket ss=new ServerSocket(9999);

//等待某個客戶端來連接,該函數會返回一個Scoket連接

Socket s=ss.accept();

}

   

}

   

代碼2

   

創建一個類,名字叫Client

   

public class MyClient1 {

public MyClient1()

{

//Socket,就是連接某個服務器端,127.0.0.1表示服務器的Ip 9999表示端口號

Socket s=new Socket("127.0.0.1", 9999);

}

}

   

服務器和客戶端互發信息

   

服務器端和客戶端是如何發送信息的呢,用到的還是java.io包下的東西,服務器端要讀取客戶端發來的信息,用到InputStreamReaderBufferedReader,其中InputStreamReader的輸入為Socket.getInputStream()方法返回的輸入流,要發送信息給客戶端用到PrintWriter,其中PrintWriter的輸入為Socket.getOutputStream()方法返回的輸出流,具體用法如下

   

客戶端發送信息

//如果s連接成功,就可以發數據給服務器

//我們通過pws寫數據 true表示刷新流

PrintWriter pw=new PrintWriter(s.getOutputStream(),true);

pw.println("Hello ServerI'm Client");

   

服務器端接受信息

//要讀取s中傳遞的數據

InputStreamReader isr=new InputStreamReader(s.getInputStream());

BufferedReader br=new BufferedReader (isr);

//行讀取

String info=br.readLine();

System.out.println("服務器收到的信息是,"+info);

   

然后服務器端向客戶端發送信息

PrintWriter pw=new PrintWriter(s.getOutputStream(), true);

pw.println("Hello ClientI'm Server");

   

然后客戶端收到服務器端的信息

InputStreamReader isr=new InputStreamReader(s.getInputStream());

BufferedReader br=new BufferedReader (isr);

//行讀取

String response=br.readLine();

System.out.println("客戶端收到的信息是,"+response);

   

服務器和客戶端互發信息(從控制台輸入)

   

之前服務器和客戶端互發的信息是寫死在pw.println里,我們稍微修改一下,從控制台輸入

   

之前建立連接的方式相同,而且讀取和發送信息的方式也類似,只是多了一個需要從控制台輸入信息

   

服務器端代碼

   

比如服務器端接受客戶端發來的信息依舊不變,從Socket.getInputStream()方法返回的輸入流作為InputStreamReader的輸入

   

但服務器端還需要一個InputStreamReader接受從System.in傳進來的輸入用來接收從控制台輸入的想發送給客戶端的信息

   

//接受客戶端發來的信息

InputStreamReader isr=new InputStreamReader(s.getInputStream());

BufferedReader br=new BufferedReader(isr);

//打印客戶端發來的信息

String infoFromClient=br.readLine();

System.out.println("客戶端發來"+infoFromClient);

   

//接收從控制台輸入的信息

InputStreamReader isr2=new InputStreamReader(System.in);

BufferedReader br2=new BufferedReader(isr2);

//打印從控制台輸入的信息

System.out.println("輸入要發送給客戶端的信息");

String response=br2.readLine();

   

客戶端的代碼

   

而客戶端代碼也類似

   

InputStreamReader isr=new InputStreamReader(System.in);

BufferedReader br=new BufferedReader(isr);

   

InputStreamReader isr2=new InputStreamReader(s.getInputStream());

BufferedReader br2=new BufferedReader(isr2);

   

服務器和客戶端互發信息(從聊天窗口輸入)

   

有了第一個的基礎,這一部分就只是將從控制台輸入變成了從JTextArea域里讀取文字,這里我們暫且認為已有Java界面的基礎,對JFrame了解

   

這一部分我們希望客戶端發來的消息顯示在聊天窗口中,而不是控制台,那么將

System.out.println("客戶端發來"+infoFromClient);替代為jta.append("客戶端發來"+info+"\r\n");即可

   

另外我們希望客戶端發給服務器的消息也從聊天窗口輸入,那么我們需要繼承ActionListener,實現當點擊發送按鈕時,讀取JTextField域的文字,具體實現如下

   

String info=jtf.getText();

pw.println(info);

//清空發送框的內容

jtf.setText("");

   

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM