重复和并发服务器
这个应用程序被当作一个重复的服务器因为它只有在处理完一个进程以后才会接受另一个连接更多的复杂服务器是并发的它为每一个请求分配一个线程而不是来一个处理一个所以看起来它在同时处理多人请求所有的商业的服务器都是并发的服务器
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);
}
}
}