Java/Network Protocol/TCP

Материал из Java эксперт
Перейти к: навигация, поиск

A tcp client, a tcp server, and a Serializable payload object which is sent from the server to the client

//The 3 classes are a a tcp client, tcp server, and a Serializable payload object which is sent from the server to the client.
//The 3 classes are meant to work together.
//--George

//TcpClient.java -------------------------------------------------------------------------------------------------------------------------
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * TcpClient.java
 *
 * This class works in conjunction with TcpServer.java and TcpPayload.java
  *
 * This client test class connects to server class TcpServer, and in response,
* it receives a serialized an instance of TcpPayload.
 */
public class TcpClient
{
    public final static String SERVER_HOSTNAME = "gsoler.arc.nasa.gov";
    public final static int COMM_PORT = 5050;  // socket port for client comms
    private Socket socket;
    private TcpPayload payload;
    /** Default constructor. */
    public TcpClient()
    {
        try
        {
            this.socket = new Socket(SERVER_HOSTNAME, COMM_PORT);
            InputStream iStream = this.socket.getInputStream();
            ObjectInputStream oiStream = new ObjectInputStream(iStream);
            this.payload = (TcpPayload) oiStream.readObject();
        }
        catch (UnknownHostException uhe)
        {
            System.out.println("Don"t know about host: " + SERVER_HOSTNAME);
            System.exit(1);
        }
        catch (IOException ioe)
        {
            System.out.println("Couldn"t get I/O for the connection to: " +
                SERVER_HOSTNAME + ":" + COMM_PORT);
            System.exit(1);
        }
        catch(ClassNotFoundException cne)
        {
            System.out.println("Wanted class TcpPayload, but got class " + cne);
        }
        System.out.println("Received payload:");
        System.out.println(this.payload.toString());
    }
    /**
     * Run this class as an application.
     */
    public static void main(String[] args)
    {
        TcpClient tcpclient = new TcpClient();
    }
}
TcpServer.java -------------------------------------------------------------------------------------------------------------------------
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
/**
 * This class works in conjunction with TcpClient.java and TcpPayload.java
 *
 * This server test class opens a socket on localhost and waits for a client
 * to connect. When a client connects, this server serializes an instance of
 * TcpPayload and sends it to the client.
 */
public class TcpServer
{
    public final static int COMM_PORT = 5050;  // socket port for client comms
    private ServerSocket serverSocket;
    private InetSocketAddress inboundAddr;
    private TcpPayload payload;
    /** Default constructor. */
    public TcpServer()
    {
        this.payload = new TcpPayload();
        initServerSocket();
        try
        {
            while (true)
            {
                // listen for and accept a client connection to serverSocket
                Socket sock = this.serverSocket.accept();
                OutputStream oStream = sock.getOutputStream();
                ObjectOutputStream ooStream = new ObjectOutputStream(oStream);
                ooStream.writeObject(this.payload);  // send serilized payload
                ooStream.close();
                Thread.sleep(1000);
            }
        }
        catch (SecurityException se)
        {
            System.err.println("Unable to get host address due to security.");
            System.err.println(se.toString());
            System.exit(1);
        }
        catch (IOException ioe)
        {
            System.err.println("Unable to read data from an open socket.");
            System.err.println(ioe.toString());
            System.exit(1);
        }
        catch (InterruptedException ie) { }  // Thread sleep interrupted
        finally
        {
            try
            {
                this.serverSocket.close();
            }
            catch (IOException ioe)
            {
                System.err.println("Unable to close an open socket.");
                System.err.println(ioe.toString());
                System.exit(1);
            }
        }
    }
    /** Initialize a server socket for communicating with the client. */
    private void initServerSocket()
    {
        this.inboundAddr = new InetSocketAddress(COMM_PORT);
        try
        {
            this.serverSocket = new java.net.ServerSocket(COMM_PORT);
            assert this.serverSocket.isBound();
            if (this.serverSocket.isBound())
            {
                System.out.println("SERVER inbound data port " +
                    this.serverSocket.getLocalPort() +
                    " is ready and waiting for client to connect...");
            }
        }
        catch (SocketException se)
        {
            System.err.println("Unable to create socket.");
            System.err.println(se.toString());
            System.exit(1);
        }
        catch (IOException ioe)
        {
            System.err.println("Unable to read data from an open socket.");
            System.err.println(ioe.toString());
            System.exit(1);
        }
    }
    /**
     * Run this class as an application.
     */
    public static void main(String[] args)
    {
        TcpServer tcpServer = new TcpServer();
    }
}
TcpPayload.java -------------------------------------------------------------------------------------------------------------------------
import java.io.Serializable;
/**
 * This class works in conjunction with TcpClient.java and TcpServer.java
 *
 * This class contains test data representing a "payload" that is sent from
 * TcpServer to TcpClient. An object of this class is meant to be serialized by
 * the server before being sent to the client. An object of this class is meant
 * to be deserialized by the client after being received.
 */
public class TcpPayload implements Serializable
{
    // serial version UID was generated with serialver command
    static final long serialVersionUID = -50077493051991107L;
    private int int1;
    private transient int int2;  // transient members are not serialized
    private float float1;
    private double double1;
    private short short1;
    private String str1;
    private long long1;
    private char char1;
    /** Default constructor. */
    public TcpPayload()
    {
        this.int1 = 123;
        this.int2 = 456;
        this.float1 = -90.05f;
        this.double1 = 55.055;
        this.short1 = 59;
        this.str1 = "I am a String payload.";
        this.long1 = -23895901L;
        this.char1 = "x";
    }
    /** Get a String representation of this class. */
    public String toString()
    {
        StringBuilder strB = new StringBuilder();
        strB.append("int1=" + this.int1);
        strB.append(" int2=" + this.int2);
        strB.append(" float1=" + this.float1);
        strB.append(" double1=" + this.double1);
        strB.append(" short1=" + this.short1);
        strB.append(" str1=" + this.str1);
        strB.append(" long1=" + this.long1);
        strB.append(" char1=" + this.char1);
        return strB.toString();
    }
}





Connects to the default chargen service port

/*
 * Copyright 2001-2005 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package examples;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.net.InetAddress;
import java.net.SocketException;
import org.apache.rumons.net.CharGenTCPClient;
import org.apache.rumons.net.CharGenUDPClient;
/***
 * This is an example program demonstrating how to use the CharGenTCPClient
 * and CharGenUDPClient classes.  This program connects to the default
 * chargen service port of a specified server, then reads 100 lines from
 * of generated output, writing each line to standard output, and then
 * closes the connection.  The UDP invocation of the program sends 50
 * datagrams, printing the reply to each.
 * The default is to use the TCP port.  Use the -udp flag to use the UDP
 * port.
 * <p>
 * Usage: chargen [-udp] <hostname>
 * <p>
 ***/
public class chargen
{
    public static final void chargenTCP(String host) throws IOException
    {
        int lines = 100;
        String line;
        CharGenTCPClient client = new CharGenTCPClient();
        BufferedReader chargenInput;
        // We want to timeout if a response takes longer than 60 seconds
        client.setDefaultTimeout(60000);
        client.connect(host);
        chargenInput =
            new BufferedReader(new InputStreamReader(client.getInputStream()));
        // We assume the chargen service outputs lines, but it really doesn"t
        // have to, so this code might actually not work if no newlines are
        // present.
        while (lines-- > 0)
        {
            if ((line = chargenInput.readLine()) == null)
                break;
            System.out.println(line);
        }
        client.disconnect();
    }
    public static final void chargenUDP(String host) throws IOException
    {
        int packets = 50;
        byte[] data;
        InetAddress address;
        CharGenUDPClient client;
        address = InetAddress.getByName(host);
        client = new CharGenUDPClient();
        client.open();
        // If we don"t receive a return packet within 5 seconds, assume
        // the packet is lost.
        client.setSoTimeout(5000);
        while (packets-- > 0)
        {
            client.send(address);
            try
            {
                data = client.receive();
            }
            // Here we catch both SocketException and InterruptedIOException,
            // because even though the JDK 1.1 docs claim that
            // InterruptedIOException is thrown on a timeout, it seems
            // SocketException is also thrown.
            catch (SocketException e)
            {
                // We timed out and assume the packet is lost.
                System.err.println("SocketException: Timed out and dropped packet");
                continue;
            }
            catch (InterruptedIOException e)
            {
                // We timed out and assume the packet is lost.
                System.err.println(
                    "InterruptedIOException: Timed out and dropped packet");
                continue;
            }
            System.out.write(data);
            System.out.flush();
        }
        client.close();
    }

    public static final void main(String[] args)
    {
        if (args.length == 1)
        {
            try
            {
                chargenTCP(args[0]);
            }
            catch (IOException e)
            {
                e.printStackTrace();
                System.exit(1);
            }
        }
        else if (args.length == 2 && args[0].equals("-udp"))
        {
            try
            {
                chargenUDP(args[1]);
            }
            catch (IOException e)
            {
                e.printStackTrace();
                System.exit(1);
            }
        }
        else
        {
            System.err.println("Usage: chargen [-udp] <hostname>");
            System.exit(1);
        }
    }
}





Connects to the default echo service port

/*
 * Copyright 2001-2005 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package examples;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.SocketException;
import org.apache.rumons.net.EchoTCPClient;
import org.apache.rumons.net.EchoUDPClient;
/***
 * This is an example program demonstrating how to use the EchoTCPClient
 * and EchoUDPClient classes.  This program connects to the default echo
 * service port of a specified server, then reads lines from standard
 * input, writing them to the echo server, and then printing the echo.
 * The default is to use the TCP port.  Use the -udp flag to use the UDP
 * port.
 * <p>
 * Usage: echo [-udp] <hostname>
 * <p>
 ***/
public class echo
{
    public static final void echoTCP(String host) throws IOException
    {
        EchoTCPClient client = new EchoTCPClient();
        BufferedReader input, echoInput;
        PrintWriter echoOutput;
        String line;
        // We want to timeout if a response takes longer than 60 seconds
        client.setDefaultTimeout(60000);
        client.connect(host);
        System.out.println("Connected to " + host + ".");
        input = new BufferedReader(new InputStreamReader(System.in));
        echoOutput =
            new PrintWriter(new OutputStreamWriter(client.getOutputStream()), true);
        echoInput =
            new BufferedReader(new InputStreamReader(client.getInputStream()));
        while ((line = input.readLine()) != null)
        {
            echoOutput.println(line);
            System.out.println(echoInput.readLine());
        }
        client.disconnect();
    }
    public static final void echoUDP(String host) throws IOException
    {
        int length, count;
        byte[] data;
        String line;
        BufferedReader input;
        InetAddress address;
        EchoUDPClient client;
        input = new BufferedReader(new InputStreamReader(System.in));
        address = InetAddress.getByName(host);
        client = new EchoUDPClient();
        client.open();
        // If we don"t receive an echo within 5 seconds, assume the packet is lost.
        client.setSoTimeout(5000);
        System.out.println("Ready to echo to " + host + ".");
        // Remember, there are no guarantees about the ordering of returned
        // UDP packets, so there is a chance the output may be jumbled.
        while ((line = input.readLine()) != null)
        {
            data = line.getBytes();
            client.send(data, address);
            count = 0;
            do
            {
                try
                {
                    length = client.receive(data);
                }
                // Here we catch both SocketException and InterruptedIOException,
                // because even though the JDK 1.1 docs claim that
                // InterruptedIOException is thrown on a timeout, it seems
                // SocketException is also thrown.
                catch (SocketException e)
                {
                    // We timed out and assume the packet is lost.
                    System.err.println(
                        "SocketException: Timed out and dropped packet");
                    break;
                }
                catch (InterruptedIOException e)
                {
                    // We timed out and assume the packet is lost.
                    System.err.println(
                        "InterruptedIOException: Timed out and dropped packet");
                    break;
                }
                System.out.print(new String(data, 0, length));
                count += length;
            }
            while (count < data.length);
            System.out.println();
        }
        client.close();
    }

    public static final void main(String[] args)
    {
        if (args.length == 1)
        {
            try
            {
                echoTCP(args[0]);
            }
            catch (IOException e)
            {
                e.printStackTrace();
                System.exit(1);
            }
        }
        else if (args.length == 2 && args[0].equals("-udp"))
        {
            try
            {
                echoUDP(args[1]);
            }
            catch (IOException e)
            {
                e.printStackTrace();
                System.exit(1);
            }
        }
        else
        {
            System.err.println("Usage: echo [-udp] <hostname>");
            System.exit(1);
        }
    }
}





Finger Socket

import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
public class finger {
  public final static int port = 79;
  public static void main(String[] args) {
    String hostname;
    Socket theSocket;
    DataInputStream theFingerStream;
    PrintStream ps;
    try {
      hostname = args[0];
    }
    catch (Exception e) {
      hostname = "localhost";
    }
    try {
      theSocket = new Socket(hostname, port, true);
      ps = new PrintStream(theSocket.getOutputStream());
      for (int i = 1; i < args.length; i++) ps.print(args[i] + " ");
      ps.print("\r\n");
      theFingerStream = new DataInputStream(theSocket.getInputStream());
      String s;
      while ((s = theFingerStream.readLine()) != null) {
        System.out.println(s);
      }
    }
    catch (IOException e) {
      System.err.println(e);
    }
  }
}





Get Socket Information

import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
public class getSocketInfo {
  public static void main(String[] args) {
    for (int i = 0; i < args.length; i++) {
      try {
        Socket theSocket = new Socket(args[i], 80);
        System.out.println("Connected to " + theSocket.getInetAddress()
            + " on port " + theSocket.getPort() + " from port "
            + theSocket.getLocalPort() + " of " + theSocket.getLocalAddress());
      } // end try
      catch (UnknownHostException e) {
        System.err.println("I can"t find " + args[i]);
      } catch (SocketException e) {
        System.err.println("Could not connect to " + args[i]);
      } catch (IOException e) {
        System.err.println(e);
      }
    }
  }
}





Multicast Sender

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
public class MulticastSender {
  public static void main(String[] args) {
    InetAddress ia = null;
    int port = 0;
    String characters = "Here"s some multicast data\n";
    byte[] data = new byte[characters.length()];
    // read the address from the command line
    try {
      try {
        ia = InetAddress.getByName(args[0]);
      } catch (UnknownHostException e) {
        //ia = InetAddressFactory.newInetAddress(args[0]);
      }
      port = Integer.parseInt(args[1]);
    } catch (Exception e) {
      System.err.println(e);
      System.err.println("Usage: java MulticastSender MulticastAddress port");
      System.exit(1);
    }
    characters.getBytes(0, characters.length(), data, 0);
    DatagramPacket dp = new DatagramPacket(data, data.length, ia, port);
    try {
      MulticastSocket ms = new MulticastSocket();
      ms.joinGroup(ia);
      for (int i = 1; i < 10; i++) {
        ms.send(dp, (byte) 1);
      }
      ms.leaveGroup(ia);
      ms.close();
    } catch (SocketException se) {
      System.err.println(se);
    } catch (IOException ie) {
      System.err.println(ie);
    }
  }
}





Multicast Sniffer

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
public class MulticastSniffer {
  public static void main(String[] args) {
  
    InetAddress ia = null;
    byte[] buffer = new byte[65509];
    DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
    int port = 0;
  
    try {
      try {
        ia = InetAddress.getByName(args[0]);
      }
      catch (UnknownHostException e)  {
        //
      }
      port = Integer.parseInt(args[1]);
    }  // end try
    catch (Exception e) {
      System.err.println(e);
      System.err.println("Usage: java MulticastSniffer MulticastAddress port");
      System.exit(1);
    }
  
    try {
      MulticastSocket ms = new MulticastSocket(port);
      ms.joinGroup(ia);
      while (true) {
        ms.receive(dp);
        String s = new String(dp.getData(), 0, 0, dp.getLength());
        System.out.println(s);
      }
    }
    catch (SocketException se) {
      System.err.println(se);
    }
    catch (IOException ie) {
      System.err.println(ie);
    }  
  
  }
}





Use the Daytime TCP and Daytime UDP classes

/*
 * Copyright 2001-2005 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package examples;
import java.io.IOException;
import java.net.InetAddress;
import org.apache.rumons.net.DaytimeTCPClient;
import org.apache.rumons.net.DaytimeUDPClient;
/***
 * This is an example program demonstrating how to use the DaytimeTCP
 * and DaytimeUDP classes.
 * This program connects to the default daytime service port of a
 * specified server, retrieves the daytime, and prints it to standard output.
 * The default is to use the TCP port.  Use the -udp flag to use the UDP
 * port.
 * <p>
 * Usage: daytime [-udp] <hostname>
 * <p>
 ***/
public class daytime
{
    public static final void daytimeTCP(String host) throws IOException
    {
        DaytimeTCPClient client = new DaytimeTCPClient();
        // We want to timeout if a response takes longer than 60 seconds
        client.setDefaultTimeout(60000);
        client.connect(host);
        System.out.println(client.getTime().trim());
        client.disconnect();
    }
    public static final void daytimeUDP(String host) throws IOException
    {
        DaytimeUDPClient client = new DaytimeUDPClient();
        // We want to timeout if a response takes longer than 60 seconds
        client.setDefaultTimeout(60000);
        client.open();
        System.out.println(client.getTime(
                                          InetAddress.getByName(host)).trim());
        client.close();
    }

    public static final void main(String[] args)
    {
        if (args.length == 1)
        {
            try
            {
                daytimeTCP(args[0]);
            }
            catch (IOException e)
            {
                e.printStackTrace();
                System.exit(1);
            }
        }
        else if (args.length == 2 && args[0].equals("-udp"))
        {
            try
            {
                daytimeUDP(args[1]);
            }
            catch (IOException e)
            {
                e.printStackTrace();
                System.exit(1);
            }
        }
        else
        {
            System.err.println("Usage: daytime [-udp] <hostname>");
            System.exit(1);
        }
    }
}