重復和並發服務器
這個應用程序被當作一個重復的服務器因為它只有在處理完一個進程以後才會接受另一個連接更多的復雜服務器是並發的它為每一個請求分配一個線程而不是來一個處理一個所以看起來它在同時處理多人請求所有的商業的服務器都是並發的服務器
Java數據報類不像面向連接的類數據報的客戶端和服務器端的類在表面上是一樣的下面的程序建立了一個客戶和服務器商的數據報sockets
DatagramSocket serverSocket = new DatagramSocket( );
DatagramSocket clientSocket = new DatagramSocket();
服務器用參數來指定端口號由於客戶端將要呼叫服務器客戶端可以利用可利用的端口如果省略第二個參數程序會讓操作系統分配一個可用的端口客戶端可以請求一個指定的端口但是如果其它的應用程序已經綁定到這個端口之上請求將會失敗如果你的意圖不是作為一個服務器最好不要指定端口
由於流不能由交談得到那麼我麼如何與一個數據報Socket進行對話答案在於數據報類
接收數據報
DatagramPacket類是用來通過DatagramSocket類接收和發送數據的類packet類包括了連接信息和數據就如前面所說的一樣數據報是自身獨立的傳輸單元DatagramPacket類壓縮了這些單元下面的程序表示了用一個數據報socket來接收數據
DatagramPacket packet = new DatagramPacket(new byte[] );
clientSocketreceive(packet);
clientSocketreceive(packet);
packet的構建器需要知道將得到的數據放在哪兒一個字節的緩存被建立並且作為構建器的第二個參數每二個構建器參數是緩存的大小就像ServerSocket類的accept()方法一樣receive()方法在數據可用之前將會阻塞
發送數據報
發送數據報是非常地簡單地所有需要的只是一個地址地址是由InetAddress類來建立的這個類沒有公共的構建器但是它有幾個static的方法可以用來建立這個類的實例下面的列表列出了建立InetAddress類的實例的方法
Public InetAddress Creation MethodsInetAddress getByName(String host);
InetAddress[] getAllByName(String host);
InetAddress getLocalHost();
得到本地主機的地址是非常地有用的只有前面兩個方法是用來發送數據包的getByName()和getAllByName()需要目的主機的地址第一個方法僅僅只是返回第一個符合條件的東西第二個方法是必須的因為一台計算機可能有多個地址在這種情況下這台計算機被稱為multihomed所有的建立的方法都被標記為static它們必須像下面這樣得到調用
InetAddress addr = InetAddressgetByName(merlin);
InetAddress addr[] = InetAddressgetAllByName(merlin);
InetAddress addr = InetAddressgetLocalHost();
重復和並發服務器
所有的這些調用都可以擲出一個UnknownHostException違例如果一台計算機沒有連接上DNS服務器或者主機的確沒有找到這個違例就會被擲出如果一台計算機沒有一個激活的TCP/IP配置getLocalHost()也為失敗並擲出一個違例一旦一個地址被確定了數據報就可以被送出了下面的程序傳輸了一個字符串給目的socket
String toSend = This is the data to send!);
byte[] sendbuf = new byte[ toSendlength() ];
toSendgetBytes( toSendlength() sendbuf );
DatagramPacket sendPacket = new DatagramPacket( sendbuf sendbuflengthaddr port);
clientSocketsend( sendPacket );
首先字符串必須被轉換成一個字節數組然後一個新的DatagramPacket實例必須被建立注意構建器的最後兩個參數因為要發送一個包所以地址和端口必須被給定一個applet可能可以知道它的服務器的地址但是服務器如何知道它的客戶機的地址呢當任何一個包被收到後返回的地址和端口會被解壓出來並通過getAddress()和getPort()方法得到這就是一個服務器如何回應一個客戶端的包
DatagramPacket sendPacket = new DatagramPacket( sendbuf sendbuflengthrecvPacketgetAddress() recvPacketgetPort() );
serverSocketsend( sendPacket );
不像面向連接的操作數據報服務器服務器其實比數據報客戶端更簡單
一個數據報服務器的基本步驟
在一個指定的端口上建立一個數據報socket
用receive方法等待進來的包
用特定的協議來回應收到的包
回到第二步或繼續第二步
關閉數據報socket
列表演示了一人簡單的數據報回應服務器它將回應它收到的包
列表一個簡單的數據報回應服務器
import javaio*;
import javanet*;
public class SimpleDatagramServer
{
public static void main(String[] args)
{
DatagramSocket socket = null;
DatagramPacket recvPacket sendPacket;
try
{
socket = new DatagramSocket();
while (socket != null)
{
recvPacket= new DatagramPacket(new byte[] );
socketreceive(recvPacket);
sendPacket = new DatagramPacket(recvPacketgetData() recvPacketgetLength()recvPacketgetAddress() recvPacketgetPort() );
socketsend( sendPacket );
}
}
catch (SocketException se)
{
Systemoutprintln(Error in SimpleDatagramServer: + se);
}
catch (IOException ioe)
{
Systemoutprintln(Error in SimpleDatagramServer: + ioe);
}
}
}
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27214.html