反射镜 : 服务器 « 网络协议 « Java

En
Java
1. 图形用户界面
2. 三维图形动画
3. 高级图形
4. 蚂蚁编译
5. Apache类库
6. 统计图
7. 
8. 集合数据结构
9. 数据类型
10. 数据库JDBC
11. 设计模式
12. 开发相关类
13. EJB3
14. 电子邮件
15. 事件
16. 文件输入输出
17. 游戏
18. 泛型
19. GWT
20. Hibernate
21. 本地化
22. J2EE平台
23. 基于J2ME
24. JDK-6
25. JNDI的LDAP
26. JPA
27. JSP技术
28. JSTL
29. 语言基础知识
30. 网络协议
31. PDF格式RTF格式
32. 映射
33. 常规表达式
34. 脚本
35. 安全
36. Servlets
37. Spring
38. Swing组件
39. 图形用户界面
40. SWT-JFace-Eclipse
41. 线程
42. 应用程序
43. Velocity
44. Web服务SOA
45. 可扩展标记语言
Java 教程
Java » 网络协议 » 服务器屏幕截图 
反射镜
 

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;

public class Reflector implements Runnable {

  // valid names found in the config file:
  public static final String MODE = "Mode";

  public static final String SOURCE_IP = "SourceIP";

  public static final String SOURCE_PORT = "SourcePort";

  public static final String DEST_IP = "DestIP";

  public static final String DEST_PORT = "DestPort";

  // valid modes in the config file, unicast to
  // multicast or multicast to unicast
  public static final String INPUT_UNITOMULTI = "UNI_TO_MULTI";

  public static final String INPUT_MULTITOUNI = "MULTI_TO_UNI";

  // possible modes the reflector can be set to:
  public static final int MODE_NONE = 0;

  public static final int MODE_UNI_TO_MULTI = 1;

  public static final int MODE_MULTI_TO_UNI = 2;

  // variables to indicate source or destination
  public static final int SOURCE = 1;

  public static final int DEST = 2;

  // min and max network ports allowed
  public static final int MIN_PORT = 1024;

  public static final int MAX_PORT = 65095;

  // which mode the reflector is being run in:
  private int mode = 0;

  // source and destination hold variables:
  private Address source;

  private Hashtable dest;

  private Address hold_dest = null;

  // logging toggle and logger class
  boolean logging = true;

  Logger logger;

  public Reflector() {
  }

  public void run() {
    // validate the config file
    if (readConfig() != 0) {
      System.err.println("Error parsing config file\n");
      System.exit(-1);
    }

    // start the logger
    logger = new Logger(logging);

    // spawn a thread to listen for packets
    ReflectorListener listener = new ReflectorListener(source, mode, logger);
    System.out.println("Listening on " + source.toString());

    // spawn threads for each source address packets
    // are to be forwarded on. Register each thread as
    // PacketListenerInterface with the listener thread.
    System.out.println("Sending on:");
    for (Enumeration e = dest.elements(); e.hasMoreElements();) {
      Address a = (Addresse.nextElement();
      ReflectorSender sender = new ReflectorSender(a, mode, logger);
      sender.start();
      listener.addPacketListener((PacketListenerInterfacesender);
      System.out.println("           " + a.toString());
    }

    // start the listener
    listener.start();
  }

  public int readConfig() {
    // validate the contents of the config file

    BufferedReader input = null;
    String name, value, inputLine = null;

    dest = new Hashtable();

    // open and read the config file
    try {
      input = new BufferedReader(new FileReader("reflector.conf"));
      inputLine = input.readLine();
    catch (IOException e) {
      System.err.println("Error reading reflector.conf.");
      return (-1);
    }

    // loop until entire config file is read
    while (inputLine != null) {

      // skip comments:
      if (inputLine.charAt(0!= '#') {

        // extract a name/value pair, and branch
        // based on the name:

        StringTokenizer tokenizer = new StringTokenizer(inputLine, "=");
        name = tokenizer.nextToken();
        value = tokenizer.nextToken();

        if (name == null) {
          System.out.println("no name");
          continue;
        else if (name.equals(MODE)) {
          if (setMode(value!= 0) {
            System.err.println("Error setting mode to " + value);
            return (-1);
          }
        else if (name.equals(SOURCE_IP)) {
          if (setSourceIP(value!= 0) {
            System.err.println("Error setting src IP address to "
                + value);
            return (-1);
          }
        else if (name.equals(SOURCE_PORT)) {
          if (setSourcePort(value!= 0) {
            System.err
                .println("Error setting src port to " + value);
            return (-1);
          }
        else if (name.equals(DEST_IP)) {
          if (setDestIP(value!= 0) {
            System.err.println("Error setting dest IP address to "
                + value);
            return (-1);
          }
        else if (name.equals(DEST_PORT)) {
          if (setDestPort(value!= 0) {
            System.err.println("Error setting dest port to "
                + value);
            return (-1);
          }
        else {
          System.err.println("Skipping invalid config file value: "
              + name);
        }
      }
      // read next line in the config file
      try {
        inputLine = input.readLine();
      catch (IOException e) {
        System.err.println("Error reading reflector.conf.");
        return (-1);
      }
    }

    // close the config file
    try {
      input.close();
    catch (IOException e) {
      System.err.println("Error closing reflector.conf.");
      return (-1);
    }

    // validate that the combined contents of the config file
    // make sense
    if (!isConfigValid()) {
      System.err.println("Configuration file is not complete.");
      return (-1);
    }
    return (0);
  }

  private int setMode(String value) {
    // validate and set the mode from the config file
    if (value.equals(INPUT_UNITOMULTI)) {
      mode = MODE_UNI_TO_MULTI;
      return (0);
    else if (value.equals(INPUT_MULTITOUNI)) {
      mode = MODE_MULTI_TO_UNI;
      return (0);
    else {
      return (-1);
    }
  }

  private int setSourceIP(String value) {
    // validate and set the source IP from the config file

    // call modeToAddress to validate IP address
    InetAddress inet = modeToAddress(value, SOURCE);
    if (inet == null)
      return -1;

    if (source != null) {
      if (source.getAddress() != null)
        System.err.println("Warning: overwriting src address "
            + source.getAddress().getHostAddress() " with "
            + inet.getHostAddress() ".");
      source.setAddress(inet);
    else {
      source = new Address(inet);
    }

    return (0);
  }

  private int setSourcePort(String value) {
    // validate and set the source port from the config file

    int port;

    try {
      port = Integer.parseInt(value);
    catch (NumberFormatException nfe) {
      return (-1);
    }

    if ((port < MIN_PORT|| (port > 65095))
      return (-1);

    if (source != null) {
      if (source.getPort() != 0)
        System.err.println("Warning: overwriting src port "
            + source.getPort() " with port " + port + ".");
      source.setPort(port);
    else {
      source = new Address(port);
    }

    return (0);
  }

  private int setDestIP(String value) {
    // validate and set the dest IP from the config file

    // call modeToAddress to validate IP address
    InetAddress inet = modeToAddress(value, DEST);
    if (inet == null)
      return -1;

    if (hold_dest != null) {
      if (hold_dest.getAddress() != null)
        System.err.println("Warning: overwriting dest address "
            + hold_dest.getAddress().getHostAddress() " with "
            + inet.getHostAddress() ".");
      hold_dest.setAddress(inet);
      if (hold_dest.isComplete())
        return (addDest());
    else {
      hold_dest = new Address(inet);
    }
    return (0);
  }

  private int setDestPort(String value) {
    // validate and set the dest port from the config file

    int port;

    try {
      port = Integer.parseInt(value);
    catch (NumberFormatException nfe) {
      return (-1);
    }

    if ((port < MIN_PORT|| (port > MAX_PORT))
      return (-1);

    if (hold_dest != null) {
      if (hold_dest.getPort() != 0)
        System.err.println("Warning: overwriting dest port "
            + hold_dest.getPort() " with port " + port + ".");
      hold_dest.setPort(port);
      if (hold_dest.isComplete())
        return (addDest());
    else {
      hold_dest = new Address(port);
    }

    return (0);
  }

  private int addDest() {
    // once both a dest IP and port have been read, add them
    // to our vector of all destinations.

    switch (mode) {
    case MODE_UNI_TO_MULTI:
      if (!dest.isEmpty()) {
        System.err.println("Warning: dest address overwritten");
        dest.clear();
      }
      dest.put(hold_dest.toString(), hold_dest);
      break;
    case MODE_MULTI_TO_UNI:
      dest.put(hold_dest.toString(), hold_dest);
      break;
    default:
      // no mode set
      System.err.println("Destination " + hold_dest.toString()
          " skipped because no mode set.");
      hold_dest = null;
      return (-1);
    }
    hold_dest = null;
    return (0);
  }

  private InetAddress modeToAddress(String value, int type) {
    // validate the IP Address based on its text value, its
    // type (DEST or SOURCE), and the mode (UNI_TO_MULTI or
    // MULTI_TO_UNI). Returns an InetAddress if succesfull and
    // null on failure.

    InetAddress inet;

    if ((type != DEST&& (type != SOURCE)) {
      System.err.println("Invalid type passed to modeToAddress (" + type
          ")");
      return (null);
    }

    switch (mode) {
    case MODE_UNI_TO_MULTI:
      if (type == DEST)
        inet = returnValidMCIP(value);
      else
        inet = returnValidIP(value);
      break;
    case MODE_MULTI_TO_UNI:
      if (type == DEST)
        inet = returnValidIP(value);
      else
        inet = returnValidMCIP(value);
      break;
    default:
      // no mode set
      System.err.println("Error: No Mode Selected.");
      return (null);
    }

    if (inet == null)
      System.err.println("Invalid dest IP address (" + value + ").");

    return (inet);
  }

  private InetAddress returnValidIP(String IP) {
    // return InetAddress if IP is valid, null otherwise

    InetAddress inet;
    try {
      inet = InetAddress.getByName(IP);
    catch (UnknownHostException e) {
      return (null);
    }
    return (inet);
  }

  private InetAddress returnValidMCIP(String IP) {
    // return InetAddress if IP is valid multicast addr,
    // null otherwise

    InetAddress inet = returnValidIP(IP);
    if (inet.isMulticastAddress()) {
      return (inet);
    else {
      return (null);
    }
  }

  public boolean isConfigValid() {
    // validate that the mode, source IP/port, and
    // dest IP(s)/port(s) are all valid and a valid
    // combination.

    if (mode == MODE_NONE) {
      System.err.println("No mode selected.");
      return (false);
    }
    if (!source.isComplete()) {
      if ((source.getPort() != 0&& (mode == MODE_UNI_TO_MULTI)) {
        // if source is unicast local IP is implied
        try {
          source.setAddress(InetAddress.getLocalHost());
        catch (UnknownHostException e) {
          System.err.println("Incomplete source address.");
          return (false);
        }
      else {
        System.err.println("Incomplete source address.");
        return (false);
      }
    }
    if (dest.isEmpty()) {
      System.err.println("No destination addresses.");
      return (false);
    }
    for (Enumeration e = dest.elements(); e.hasMoreElements();) {
      Address a = (Addresse.nextElement();
      if (!a.isComplete()) {
        System.err.println("Incompete destination address.");
        return (false);
      }
    }
    return (true);
  }

  public static void main(String args[]) {
    Reflector r = new Reflector();
    r.run();
  }
}

//Address class is used to store an IP address and port
//combination.

class Address {

  private InetAddress address = null;

  private int port = 0;

  public Address(InetAddress address, int port) {
    this.address = address;
    this.port = port;
  }

  public Address(InetAddress address) {
    this.address = address;
  }

  public Address(int port) {
    this.port = port;
  }

  public InetAddress getAddress() {
    return (address);
  }

  public int getPort() {
    return (port);
  }

  public void setPort(int port) {
    this.port = port;
  }

  public void setAddress(InetAddress address) {
    this.address = address;
  }

  public boolean isComplete() {
    // return true if both IP and port are populated,
    // false otherwise.

    if ((address != null&& (port != 0))
      return (true);
    else
      return (false);
  }

  public String toString() {
    // return a string representation of the IP/port.

    String str;

    if (address == null)
      str = "";
    else
      str = address.getHostAddress();

    str = str + "/" + port;

    return (str);
  }
}

//Logger class opens and writes to the log file
//if boolean true is passed as constructor argument.

class Logger {

  private boolean logging;

  private FileWriter logfile;

  public Logger(boolean logging) {
    this.logging = logging;

    if (logging) {
      try {
        // open logfile for append
        logfile = new FileWriter("reflector.log"true);
      catch (IOException e) {
        System.err.println("Error opening log file.");
      }
      log("Reflector started: " new Date());
    }
  }

  public void log(String str) {
    // write string to logfile

    // if logging disabled return
    if (!logging)
      return;

    try {
      logfile.write(str + "\n");
      logfile.flush();
    catch (IOException e) {
      System.err.println("Error writing to log file.");
    }
  }
}

//ReflectorSender creates a unicast or multicast socket
//and is registered to receive incoming packet notifications
//via the PacketListenerInterface. Incoming packets
//are forwarded on the outgoing socket.

class ReflectorSender extends Thread implements PacketListenerInterface {
  private InetAddress sendAddr;

  private int sendPort;

  private int mode;

  private DatagramSocket ds = null;

  private Logger logger;

  public ReflectorSender(Address a, int mode, Logger logger) {
    sendAddr = a.getAddress();
    sendPort = a.getPort();
    this.mode = mode;
    this.logger = logger;
  }

  public void run() {
    // initialize a DatagramSocket or MulticastSocket
    // based on the mode:

    switch (mode) {
    case Reflector.MODE_MULTI_TO_UNI:
      ds = initUnicastSocket();
      break;
    case Reflector.MODE_UNI_TO_MULTI:
      ds = (DatagramSocketinitMulticastSocket();
      break;
    default:
      break;
    }
  }

  private MulticastSocket initMulticastSocket() {
    // initialize a MulticastSocket

    MulticastSocket mc;
    try {
      mc = new MulticastSocket(sendPort);
    catch (Exception e) {
      e.printStackTrace();
      return (null);
    }
    return (mc);
  }

  private DatagramSocket initUnicastSocket() {
    // initialize a DatagramSocket

    DatagramSocket ds;
    try {
      ds = new DatagramSocket(sendPort);
    catch (Exception e) {
      e.printStackTrace();
      return (null);
    }
    return (ds);
  }

  public void packetReceived(DatagramPacket packet) {
    // An incoming packet has been received. Override
    // the old packet addressing to the new outgoing
    // addressing, send it and log it.

    try {
      packet.setAddress(sendAddr);
      packet.setPort(sendPort);
      ds.send(packet);
      logger.log("Packet forwarded to "
          + packet.getAddress().getHostAddress() "/"
          + packet.getPort() ", " + packet.getLength() " bytes");
    catch (IOException e) {
      System.err.println("Error sending packet");
      e.printStackTrace();
    }
  }
}

//ReflectorListener thread listens for packets
//and notifies one or more interested threads
//who register as PacketListenerInterfaces.

class ReflectorListener extends Thread {
  private InetAddress listenAddr;

  private int listenPort;

  private int mode;

  private Vector packetListeners;

  private Logger logger;

  private static final int MAX_PACKET_SIZE = 1500;

  public ReflectorListener(Address a, int mode, Logger logger) {
    listenAddr = a.getAddress();
    listenPort = a.getPort();
    this.mode = mode;
    this.logger = logger;

    packetListeners = new Vector();
  }

  public void run() {
    // create a unicast or multicast socket
    // depending on the mode and listen for packets.

    switch (mode) {
    case Reflector.MODE_UNI_TO_MULTI:
      DatagramSocket ds = initUnicastSocket();
      if (ds != null)
        listen(ds);
      break;
    case Reflector.MODE_MULTI_TO_UNI:
      MulticastSocket mc = initMulticastSocket();
      if (mc != null)
        listen((DatagramSocketmc);
      break;
    default:
      break;
    }
  }

  private MulticastSocket initMulticastSocket() {
    // initialize a MulticastSocket and join the group

    MulticastSocket mc;
    try {
      mc = new MulticastSocket(listenPort);
      mc.joinGroup(listenAddr);
    catch (Exception e) {
      System.err.println("Failed to create MulticastSocket on " "port "
          + listenPort);
      return (null);
    }
    return (mc);
  }

  private DatagramSocket initUnicastSocket() {
    // initialize a DatagramSocket

    DatagramSocket ds;
    try {
      ds = new DatagramSocket(listenPort);
    catch (Exception e) {
      System.err.println("Failed to create DatagramSocket on " "port "
          + listenPort);
      return (null);
    }
    return (ds);
  }

  private void listen(DatagramSocket ds) {
    // loop forever listening to packets, when they
    // arrive log them and notify all interested threads.

    byte[] buffer;
    DatagramPacket packet;

    while (true) {
      try {
        buffer = new byte[MAX_PACKET_SIZE];
        packet = new DatagramPacket(buffer, buffer.length);

        ds.receive(packet);

        logger.log("Packet received, " + packet.getLength() " bytes");
        eventNotify(packet);

      catch (IOException e) {
        System.err.println("Error receiving packet\n");
        e.printStackTrace();
      }
    }
  }

  public void addPacketListener(PacketListenerInterface pl) {
    // add interested thread to listeners vector
    packetListeners.addElement(pl);
  }

  public void removePacketListener(PacketListenerInterface pl) {
    // remove thread to listeners vector
    packetListeners.removeElement(pl);
  }

  private void eventNotify(DatagramPacket packet) {
    // notify all registered threads that a packet has arrived
    // using the packetReceived(DatagramPacket) method.

    for (Enumeration e = packetListeners.elements(); e.hasMoreElements();) {

      PacketListenerInterface pl = (PacketListenerInterfacee
          .nextElement();
      pl.packetReceived(packet);
    }
  }
}

//PacketListenerInterface used by threads that need to
//be notified of datagram packet receipt. A single
//interface function packetReceived passes the packet
//information to the thread requiring the information.

interface PacketListenerInterface {
  public void packetReceived(DatagramPacket packet);
}

           
         
  
Related examples in the same category
1. 通用框架:一个灵活的,多线程服务器
2. 6123端口上的服务器允许连接6123端口上的服务器允许连接
3. 此服务器显示的信息到单一客户此服务器显示的信息到单一客户
4. The client can specify information to control the output of a serverThe client can specify information to control the output of a server
5. 服务器可以使用专门的流提供输入数据服务器可以使用专门的流提供输入数据
6. 使用ObjectOutputStream服务与整个对象使用ObjectOutputStream服务与整个对象
7. 多线程服务器多线程服务器
8. Base class to build multithreaded servers easily
9. 为客户管理线程池
10. Client estimates the speed of the network connection to the server
11. 套接字Openeration试验
12. URL Connection Test URL Connection Test
13. 此服务器使用RFC867议定书检索时间此服务器使用RFC867议定书检索时间
14. 引用服务器
15. 基于SocketServer的记录服务器
16. 客户端和服务器演示
www.java2java.com | Contact Us
Copyright 2010 - 2030 Java Source and Support. All rights reserved.
All other trademarks are property of their respective owners.