謝智明
(湖南科技學院 計算機與通信工程系,湖南 永州 425100)
JAVA語言SOCKET機制的研究
謝智明
(湖南科技學院 計算機與通信工程系,湖南 永州 425100)
本文研究了JAVA語言SOCKET機制,闡述了輸入/輸出流的概念,并應用這一機制實現了C/S模式下網絡通信。
JAVA;網絡;SOCKET
Socket是面向客戶/服務器模型設計的,網絡上的兩個程序通過一個雙向的通訊連接實現數據的交換,這個雙向鏈路的一端稱為一個Socket。 Socket通常用來實現客戶方和服
務方的連接??蛻舫绦蚩梢韵?Socket寫請求,服務器將處理此請求,然后通過Socket將結果返回給用戶。
Socket通信機制提供了兩種通訊方式:有聯接和無聯接方式,分別面向不同的應用需求。使用有聯接方式時,通信鏈路提供了可靠的,全雙工的字節流服務。在該方式下,通信雙方必須創建一個聯接過程并建立一條通訊鏈路,以后的網絡通信操作完全在這一對進程之間進行,通信完畢關閉此聯接過程。使用無聯接方式時其系統開銷比無聯接方式小,但通信鏈路提供了不可靠的數據報服務,不能保證信源所傳輸的數據一定能夠到達信宿。在該方式下,通信雙方不必創建一個聯接過程和建立一條通訊鏈路,網絡通信操作在不同的主機和進程之間轉發進行。
過濾流DataInputStream 和DataOutputStream 除了分別作為 FilterInputStream 和 FilterOutputStream的子類外,還分別實現了接口DataInput 和DataOutput。接口DataInput 中定義的方法,主要包括從流中讀取基本類型的數據、讀取一行數據、或者讀取指定長度的字節數,如 readBoolean()readInt()、readLine()、readFully()等。
接口 DataOutput中定義的方法主要是向流中寫入基本類型的數據或者寫入一定長度的字節數組,如writeChar()、writeDouble() DataInputStream可以從所連接的輸入流中讀取與機器無關的基本類型數據,用以實現一種獨立于具體平臺的輸入方式;DataInputStream 可以向所連接的輸出流寫入基本類型的數據。
1、打開Socket,新建一個套接字;
2、為套接字建立一個輸入和輸出流;
3、根據服務器協議從套接字讀入或向套接字寫入;
4、清除套接字和輸入/輸出流;
1、打開Server Socket,創建一個服務器型套接字和一個普通套接字,服務器型套接字在指定端口為客戶端請求的Socket 服務;
2、使用ServerSocket類的accept()方法使服務器型套接字處于監聽狀態并把監聽結果返回給普通套接字;
3、為該普通套接字創建輸入和輸出流;
4、從輸入和輸出流中讀入或寫入字節流,進行相應的處理,并將結果返回給客戶端;
5、在客戶端和服務器工作結束后關閉所有的對象,如服務器型的套接字,普通套接字,輸入和輸出流。
正是由于Java系統具有基于Socket的靈活通信機制,因而其應用程序能自由地打開和訪問網絡上的對象,就象在本地文件系統中一樣。
服務器端程序負責與客戶端通信import java.io.*;
import java.net.*;
import java.lang.*;
import T2;
class ThreadEchoHandler extends Thread //創建線程
{
T2 theT2=new T2();
Socket incoming;
int counter;
ThreadEchoHandler(Socket i,int c)
{ incoming=i;
counter=c; }
public void run()
{ try
{
DataInputStream in=new
DataInputStream(incoming.getInputStream());
DataOutputStream out=new
DataOutputStream(incoming.get Out put Stream());
System.out.println ("hello");
boolean done=false;
while(!done)
{ String aa="";
String str=in.readUTF();
//從客戶端得到字符串
//在此加入各自的服務程序
System.out.println (str);
theT2.pass(str); //解碼
theT2.tongji();
//修改監控庫中的信息
aa=theT2.guan();
//操縱數據庫
System.out.println ("string z is:"+aa);
if(aa.compareTo("null")!=0 )//若是查詢數據庫,返回查詢后的結果
{
//若不是查詢數據庫,不向客戶端輸出信息
out.writeUTF(aa);
out.flush(); }
}//while
incoming.close(); //線程關閉
}//try
catch(IOException e)
{System.out.println(e);}
}//end run
}
//----------------------------------------
class S
{
public static void main(String[] args)
{
int i=1;
try
{
ServerSocket s=new ServerSocket(1111);
for(;;)
{
Socket incoming=s.accept();
System.out.println("connect: "+i);
new
ThreadEchoHandler(incoming,i).start();
i++;
}
}
catch(Exception e)
{ System.out.println(e); }
}
}
客戶端通信應用程序 Echo.java
import java.io.*;
import java.net.*;
import java.awt.*;
import java.applet.*;
public class Echo extends Applet
{
TextArea ta;
Socket echoSocket;
DataOutputStream os;
DataInputStream is;
String Line;
public void init()
{
setBackground(Color.white);
ta=new TextArea(5,80);
ta.setEditable(false);
add(ta);
try
{echoSocket=new Socket("10.102.4.41",1111);}
//與服務器建立連接
catch(IOException e)
{System.out.println("error");}
}
public void st(String stri) //發送字符串的 方法
{
try
{ DataOutputStream os=new
DataOutputStream(echoSocket.getOutputStream());
DataInputStream is=new
DataInputStream(echoSocket.getInputStream());
os.writeUTF(""+ stri );
//向服務器輸送string
os.flush();
}
catch(IOException e)
{System.out.println(" error:"+e); }
}
public String st1() //接收字符串的方法
{
String Line="";
try
{ DataOutputStream os=new
DataOutputStream(echoSocket.getOutputStream());
DataInputStream is=new
DataInputStream(echoSocket.getInputStream());
Line=is.readUTF();
//從服務器讀來的信息
ta.appendText(""+Line);
//在文本域中輸出信息
}
catch(IOException e)
{System.out.println(" error:"+e); }
return Line;
}
}
在建立 Socket連接時,兩端的端口號必須設為一致,否則建立不了連接。服務器端必須有主機IP地址或主機名參數。連接建立好之后應確定輸入和輸出流。起初程序中用的是DataInputStream和PrintStream,結果只能傳輸英文 ,傳輸中文時產生亂碼,將PrintStream改為DataOutput Stream,使用readUTF()和writeUTF()方法后,中文傳輸問題得到解決。如果一個使用某端口的程序沒有關閉,另一個程序就不能使用這個端口。
[1]廖雷,等.Java程序設計教程[M].北京:中國電力出版社,2003.
[2]張立,等.基于Client/Server模式的數據庫應用軟件的設計與實現[J].計算機應用研究,1999,(4).
TP311
A
1673-2219(2011)04-0070-03
2010-4-29
謝智明(1971-),湖南祁陽人,碩士,計算機軟件與技術系統分析師,研究方向為計算機及應用。
(責任編校:何俊華)