浅谈Java网络编程之Socket (1)
和大家一起分享的是Java網(wǎng)絡(luò)編程之Socket。在Java中Socket可以理解為客戶端或者服務(wù)器端的一個特殊的對象,這個對象有兩個關(guān)鍵的方法,一個是getInputStream方法,另一個是getOutputStream方法。getInputStream方法可以得到一個輸入流,客戶端的Socket對象上的getInputStream方法得到的輸入流其實就是從服務(wù)器端發(fā)回的數(shù)據(jù)流。GetOutputStream方法得到一個輸出流,客戶端Socket對象上的getOutputStream方法返回的輸出流就是將要發(fā)送到服務(wù)器端的數(shù)據(jù)流,(其實是一個緩沖區(qū),暫時存儲將要發(fā)送過去的數(shù)據(jù))。
?
?
程序可以對這些數(shù)據(jù)流根據(jù)需要進行進一步的封裝。本文的例子就對這些數(shù)據(jù)流進行了一定的封裝(關(guān)于封裝可以參考Java中流的實現(xiàn)部分)。
?
?
一、建立服務(wù)器類
?
?
Java中有一個專門用來建立Socket服務(wù)器的類,名叫ServerSocket,可以用服務(wù)器需要使用的端口號作為參數(shù)來創(chuàng)建服務(wù)器對象。
?
?
?
?
ServerSocket server = new ServerSocket(9998)
?
?
?
?
這條語句創(chuàng)建了一個服務(wù)器對象,這個服務(wù)器使用9998號端口。當(dāng)一個客戶端程序建立一個Socket連接,所連接的端口號為9998時,服務(wù)器對象server便響應(yīng)這個連接,并且server.accept()方法會創(chuàng)建一個Socket對象。服務(wù)器端便可以利用這個Socket對象與客戶進行通訊。
?
?
?
?
Socket incoming = server.accept()
?
?
?
進而得到輸入流和輸出流,并進行封裝
?
?
BufferedReader in = new BufferedReader(new
?
?
InputStreamReader(incoming.getInputStream()));
PrintWriter out = new PrintWriter(incoming.getOutputStream(),true);
?
隨后,就可以使用in.readLine()方法得到客戶端的輸入,也可以使用out.println()方法向客戶端發(fā)送數(shù)據(jù)。從而可以根據(jù)程序的需要對客戶端的不同請求進行回應(yīng)。
?
?
在所有通訊結(jié)束以后應(yīng)該關(guān)閉這兩個數(shù)據(jù)流,關(guān)閉的順序是先關(guān)閉輸出流,再關(guān)閉輸入流,即使用
?
?
?
?
out.close();
?
?
in.close();
?
?
二、建立客戶端代碼
?
?
?
?
相比服務(wù)器端,客戶端要簡單一些,客戶端只需用服務(wù)器所在機器的ip以及服務(wù)器的端口作為參數(shù)創(chuàng)建一個Socket對象。得到這個對象后,就可以用"建立服務(wù)器"部分介紹的方法實現(xiàn)數(shù)據(jù)的輸入和輸出。
?
?
?
?
Socket socket = new Socket("168.160.12.42",9998);
?
?
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(),true);
?
?
以上的程序代碼建立了一個Socket對象,這個對象連接到ip地址為168.160.12.42的主機上、端口為9998的服務(wù)器對象。并且建立了輸入流和輸出流,分別對應(yīng)服務(wù)器的輸出和客戶端的寫入。
?
?
?
?
三、建立用戶界面
?
?
?
?
讀者可以根據(jù)自己的喜好建立自己的用戶界面,這不是本文的重點。
?
?
?
?
經(jīng)過以上三個步驟,就可以建立一個比較簡單的對話程序。但是,為了使這個程序更加完善,應(yīng)進行以下幾個改進:
?
?
?
?
一、現(xiàn)在服務(wù)器只能服務(wù)一個客戶,也就是單線程的。可以將它改進為多線程服務(wù)器。
?
?
?
?
?
?
?
?
?
?
?
?
try
?
?
{ file://建立服務(wù)器
ServerSocket server = new ServerSocket(9998);
int i=1;
for(;;)
{
Socket incoming = server.accept();
new ServerThread(incoming,i).start();
i++;
}
}catch (IOException ex){ ex.printStackTrace(); }
?
?
?
?
?
?
?
?
?
?
循環(huán)檢測是否有客戶連接到服務(wù)器上,如果有,則創(chuàng)建一個線程來服務(wù)這個客戶,這個線程的名稱是ServerThread,這個類擴展了Thread類,它的編寫方法與前述的服務(wù)器的寫法相同。
?
?
?
?
二、為了可以隨時得到對方傳送過來的消息,可以在服務(wù)器以及客戶端各建立一個獨立的線程來察看輸入流,如果輸入流中有輸入,則可以即時顯示出來。代碼如下:
?
?
?
?
?
?
?
?
?
?
?
?
new Thread()
?
?
{
public void run()
{
try
{
while(true)
{
checkInput();
sleep(1000);//每1000毫秒檢測一次
}
}catch (InterruptedException ex)
{
}catch(IOException ex)
{
}
}
}.start();
?
?
其中的checkInput()方法為
?
?
private void checkInput() throws IOException
{
String line;
if((line=in.readLine())!=null) file://檢測輸入流中是否有新的數(shù)據(jù)
t.setPartner(line); file://將數(shù)據(jù)流中的消息顯示出來
}
?
通過以上改進,程序就可以比較好的運行了。
轉(zhuǎn)載于:https://www.cnblogs.com/qiforme/archive/2011/12/03/2272871.html
總結(jié)
以上是生活随笔為你收集整理的浅谈Java网络编程之Socket (1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中信i白金信用卡年费是多少?申请条件有哪
- 下一篇: Java -- 网络编程(一):Clie