home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Late Night VRML 2.0 with Java CD-ROM
/
code.zip
/
Ch18
/
Server.java
< prev
next >
Wrap
Text File
|
1997-02-21
|
14KB
|
368 lines
// Simple server, just for testing the client
// Written by Bernie Roehl, January 1997
import java.net.*;
import java.io.*;
import java.util.*;
public class Server {
public static void main(String[] args) throws SocketException, IOException {
int filter_port, update_port, text_port;
if (args.length > 0)
filter_port = Integer.parseInt(args[0]);
else
filter_port = 3000;
System.out.println("filter port is " + filter_port);
if (args.length > 1)
update_port = Integer.parseInt(args[1]);
else
update_port = filter_port + 2;
System.out.println("update port is " + update_port);
if (args.length > 2)
text_port = Integer.parseInt(args[2]);
else
text_port = filter_port + 4;
System.out.println("text port is " + text_port);
Vector connections = new Vector(); // vector of HostInfo
new ListenThread(filter_port);
new ControlThread(filter_port, connections);
new EchoThread(update_port, connections);
new TextEchoThread(text_port, connections);
}
}
class HostInfo {
InetAddress address;
int update_port;
int text_port;
}
class ControlThread extends Thread {
DatagramSocket socket;
Vector connections;
public ControlThread(int controlPort, Vector conn)
throws SocketException {
connections = conn;
socket = new DatagramSocket(controlPort);
start();
}
public void run() {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
ByteArrayInputStream bin = new ByteArrayInputStream(buffer);
DataInputStream sin = new DataInputStream(bin);
while (true) {
try { socket.receive(packet); }
catch (IOException e) {
System.out.println("could not read from control socket: " + e);
break;
}
bin.reset();
int update_port = 0, text_port = 0;
try {
update_port = sin.readUnsignedShort();
sin.readUnsignedShort(); // flags
sin.readFloat(); sin.readFloat(); sin.readFloat(); // XYZ
sin.readFloat(); // acuity
sin.readInt(); // horizon
int nregions = sin.readUnsignedShort();
while (nregions-- > 0) sin.readUnsignedShort();
int nports = sin.readUnsignedShort();
if (nports > 0) {
text_port = sin.readUnsignedShort();
}
}
catch (IOException e) {
System.out.println("could not read filter message: " + e);
break;
}
add(connections, packet.getAddress(), update_port, text_port);
}
}
private void add(Vector connections, InetAddress addr, int port, int text_port) {
synchronized(connections) {
Enumeration enum = connections.elements();
while (enum.hasMoreElements()) {
HostInfo h = (HostInfo) enum.nextElement();
if (h.address.equals(addr) && h.update_port == port) {
h.text_port = text_port;
return; // already there
}
}
HostInfo h = new HostInfo();
h.address = addr;
h.update_port = port;
h.text_port = text_port;
connections.addElement(h);
}
}
}
class EchoThread extends Thread {
DatagramSocket insocket, outsocket;
Vector connections;
public EchoThread(int dataport, Vector conn) throws SocketException {
insocket = new DatagramSocket(dataport);
outsocket = new DatagramSocket();
connections = conn;
start();
}
public void run() {
byte[] buffer = new byte[1024];
DatagramPacket inpacket = new DatagramPacket(buffer, buffer.length);
int rcount = 0, scount = 0;
while (true) {
try { insocket.receive(inpacket); }
catch (IOException e) {
System.out.println("could not read from data socket: " + e);
break;
}
DatagramPacket outpacket;
synchronized(connections) {
Enumeration enum = connections.elements();
while (enum.hasMoreElements()) {
HostInfo h = (HostInfo) enum.nextElement();
outpacket = new DatagramPacket(
inpacket.getData(), inpacket.getLength(),
h.address, h.update_port);
try { outsocket.send(outpacket); }
catch (IOException e) {
System.out.println("could not send packet: " + e);
}
}
}
}
}
}
class TextEchoThread extends Thread {
DatagramSocket insocket, outsocket;
Vector connections;
public TextEchoThread(int dataport, Vector conn) throws SocketException {
insocket = new DatagramSocket(dataport);
outsocket = new DatagramSocket();
connections = conn;
start();
}
public void run() {
byte[] buffer = new byte[1024];
DatagramPacket inpacket = new DatagramPacket(buffer, buffer.length);
int rcount = 0, scount = 0;
while (true) {
try { insocket.receive(inpacket); }
catch (IOException e) {
System.out.println("could not read from text socket: " + e);
break;
}
System.out.println("Server received text packet of size " + inpacket.getLength());
DatagramPacket outpacket;
synchronized(connections) {
Enumeration enum = connections.elements();
while (enum.hasMoreElements()) {
HostInfo h = (HostInfo) enum.nextElement();
outpacket = new DatagramPacket(
inpacket.getData(), inpacket.getLength(),
h.address, h.text_port);
try {
outsocket.send(outpacket);
}
catch (IOException e) {
System.out.println("could not send packet: " + e);
}
System.out.println("Server sent text packet of size " + outpacket.getLength());
}
}
}
}
}
class ListenThread extends Thread {
ServerSocket listen_socket;
Vector entities;
public ListenThread(int port) throws IOException {
listen_socket = new ServerSocket(port);
entities = new Vector();
start();
}
public void run() {
try {
while (true) {
Socket client_socket = listen_socket.accept();
Connection c = new Connection(client_socket, entities);
}
}
catch (IOException e) {
System.out.println("Error while listening: " + e);
return;
}
}
}
class Entity {
int id;
String cname = null;
String nickname = null;
String url = null;
String owner = null;
boolean isAvatar = false;
boolean isPersistent = false;
int textid;
long creationTime;
public Entity(String cn, int i) {
cname = new String(cn);
id = i;
creationTime = System.currentTimeMillis();
}
}
class Connection extends Thread {
protected Socket client;
protected DataInputStream in;
protected PrintStream out;
protected String ident;
protected Vector entities;
public Connection(Socket client_socket, Vector ents) {
entities = ents;
client = client_socket;
try {
in = new DataInputStream(client.getInputStream());
out = new PrintStream(client.getOutputStream());
}
catch (IOException e) {
try client.close(); catch (IOException e2);
System.out.println("error getting socket streams: " + e);
return;
}
start();
}
public void run() {
try {
while (true) {
String inputLine = in.readLine();
if (inputLine == null) {
break;
}
StringTokenizer tokens = new StringTokenizer(inputLine);
if (tokens.hasMoreTokens() == false) // empty line
continue;
String command = tokens.nextToken();
if (command.equals("HELLO")) {
out.println("WELCOME 0.1 Stub Server");
}
else if (command.equals("GOODBYE"))
break;
else if (command.equals("IDENT")) {
ident = new String(tokens.nextToken());
out.println("OKAY");
}
else if (command.equals("LIST") || command.equals("LISTNEW")) {
synchronized (entities) {
Enumeration enum = entities.elements();
while (enum.hasMoreElements()) {
Entity ent = (Entity) enum.nextElement();
out.println(ent.id);
}
}
out.println(".");
}
else if (command.equals("GETENTITY")) {
synchronized (entities) {
Entity ent = find(Integer.parseInt(tokens.nextToken()));
if (ent == null)
out.println("REFUSED no such entity");
else {
out.println(ent.cname + " " + ent.url + " "
+ ent.owner + " "
+ ent.isAvatar + " " + ent.isPersistent + " "
+ ent.creationTime);
out.println(ent.nickname);
out.println(ent.textid);
out.println(".");
}
}
}
else if (command.equals("GETINFO")) {
int entid = Integer.parseInt(tokens.nextToken());
out.println("Some User");
out.println("<not implemented>");
out.println(".");
}
else if (command.equals("ALLOC")) {
if (ident == null)
out.println("REFUSED no ident");
else {
synchronized(entities) {
int allocid = entities.size();
out.println(allocid);
Entity ent = new Entity(tokens.nextToken(), allocid);
ent.owner = new String(ident);
entities.addElement(ent);
}
}
}
else if (command.equals("RELEASE")) {
out.println("OKAY");
}
else if (command.equals("INFO")) {
out.println("OKAY");
while (in.readLine().equals(".") == false);
}
else if (command.equals("URL")) {
Entity ent = find(Integer.parseInt(tokens.nextToken()));
ent.url = new String(tokens.nextToken());
out.println("OKAY");
}
else if (command.equals("NICKNAME")) {
Entity ent = find(Integer.parseInt(tokens.nextToken()));
ent.nickname = tokens.nextToken();
while (tokens.hasMoreTokens())
ent.nickname += " " + tokens.nextToken();
out.println("OKAY");
}
else if (command.equals("AVATAR")) {
Entity ent = find(Integer.parseInt(tokens.nextToken()));
ent.isAvatar = tokens.nextElement().equals("true");
out.println("OKAY");
}
else if (command.equals("PERSISTENT")) {
Entity ent = find(Integer.parseInt(tokens.nextToken()));
ent.isPersistent = tokens.nextElement().equals("true");
out.println("OKAY");
}
else if (command.equals("TEXTID")) {
Entity ent = find(Integer.parseInt(tokens.nextToken()));
ent.textid = Integer.parseInt(tokens.nextToken());
out.println("OKAY");
}
else // catch-all
out.println("REFUSED no such command");
}
out.flush();
}
catch (IOException e);
finally try client.close(); catch (IOException e2);
}
private Entity find(int id) {
Enumeration enum = entities.elements();
while (enum.hasMoreElements()) {
Entity ent = (Entity) enum.nextElement();
if (ent.id == id)
return ent;
}
return null;
}
}