天天看點

淺談Java網絡程式設計之Socket (1)

和大家一起分享的是java網絡程式設計之socket。在java中socket可以了解為用戶端或者伺服器端的一個特殊的對象,這個對象有兩個關鍵的方法,一個是getinputstream方法,另一個是getoutputstream方法。getinputstream方法可以得到一個輸入流,用戶端的socket對象上的getinputstream方法得到的輸入流其實就是從伺服器端發回的資料流。getoutputstream方法得到一個輸出流,用戶端socket對象上的getoutputstream方法傳回的輸出流就是将要發送到伺服器端的資料流,(其實是一個緩沖區,暫時存儲将要發送過去的資料)。

程式可以對這些資料流根據需要進行進一步的封裝。本文的例子就對這些資料流進行了一定的封裝(關于封裝可以參考java中流的實作部分)。

一、建立伺服器類

java中有一個專門用來建立socket伺服器的類,名叫serversocket,可以用伺服器需要使用的端口号作為參數來建立伺服器對象。

serversocket server = new serversocket(9998)

這條語句建立了一個伺服器對象,這個伺服器使用9998号端口。當一個用戶端程式建立一個socket連接配接,所連接配接的端口号為9998時,伺服器對象server便響應這個連接配接,并且server.accept()方法會建立一個socket對象。伺服器端便可以利用這個socket對象與客戶進行通訊。

socket incoming = server.accept()

進而得到輸入流和輸出流,并進行封裝

bufferedreader in = new bufferedreader(new

inputstreamreader(incoming.getinputstream()));

printwriter out = new printwriter(incoming.getoutputstream(),true);

随後,就可以使用in.readline()方法得到用戶端的輸入,也可以使用out.println()方法向用戶端發送資料。進而可以根據程式的需要對用戶端的不同請求進行回應。

在所有通訊結束以後應該關閉這兩個資料流,關閉的順序是先關閉輸出流,再關閉輸入流,即使用

out.close();

in.close();

二、建立用戶端代碼

相比伺服器端,用戶端要簡單一些,用戶端隻需用伺服器所在機器的ip以及伺服器的端口作為參數建立一個socket對象。得到這個對象後,就可以用"建立伺服器"部分介紹的方法實作資料的輸入和輸出。

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的伺服器對象。并且建立了輸入流和輸出流,分别對應伺服器的輸出和用戶端的寫入。

三、建立使用者界面

讀者可以根據自己的喜好建立自己的使用者界面,這不是本文的重點。

經過以上三個步驟,就可以建立一個比較簡單的對話程式。但是,為了使這個程式更加完善,應進行以下幾個改進:

一、現在伺服器隻能服務一個客戶,也就是單線程的。可以将它改進為多線程伺服器。

try

{ file://建立伺服器

serversocket server = new serversocket(9998);

int i=1;

for(;;)

{

socket incoming = server.accept();

new serverthread(incoming,i).start();

i++;

}

}catch (ioexception ex){ ex.printstacktrace(); }

循環檢測是否有客戶連接配接到伺服器上,如果有,則建立一個線程來服務這個客戶,這個線程的名稱是serverthread,這個類擴充了thread類,它的編寫方法與前述的伺服器的寫法相同。

二、為了可以随時得到對方傳送過來的消息,可以在伺服器以及用戶端各建立一個獨立的線程來察看輸入流,如果輸入流中有輸入,則可以即時顯示出來。代碼如下:

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://檢測輸入流中是否有新的資料

t.setpartner(line); file://将資料流中的消息顯示出來

}

通過以上改進,程式就可以比較好的運作了。

======================================================

在最後,我邀請大家參加新浪APP,就是新浪免費送大家的一個空間,支援PHP+MySql,免費二級域名,免費域名綁定 這個是我邀請的位址,您通過這個連結注冊即為我的好友,并獲贈雲豆500個,價值5元哦!短網址是http://t.cn/SXOiLh我建立的小站每天訪客已經達到2000+了,每天挂廣告賺50+元哦,呵呵,飯錢不愁了,\(^o^)/