標籤:
引言
??
為了學習Java網路編程,用一個QQ(屌絲版)作為例子練手,記錄屌絲版QQ的開發過程,這裡我們認為已經掌握其中的網路基礎部分,即HTTP協議,TCP/IP協議等,在此基礎上我們開始我們的Java網路部分的學習,我們要知道伺服器和用戶端是如何通訊的,首先我們要瞭解Java網路知識中的一個很重要的東西——Socket
??
Socket初探
??
ServerSocket和Socket
??
首先伺服器端需要用到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包下的東西,伺服器端要讀取用戶端發來的資訊,用到InputStreamReader,BufferedReader,其中InputStreamReader的輸入為Socket.getInputStream()方法返回的輸入資料流,要發送資訊給用戶端用到PrintWriter,其中PrintWriter的輸入為Socket.getOutputStream()方法返回的輸出資料流,具體用法如下
??
用戶端發送資訊
//如果s串連成功,就可以發資料給伺服器
//我們通過pw向s寫資料 true表示重新整理流
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
pw.println("Hello Server,I‘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 Client,I‘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("");
??
??
Java網路編程——伺服器端和用戶端互發資訊