Java/Network Protocol/TCP
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
- 1 A tcp client, a tcp server, and a Serializable payload object which is sent from the server to the client
- 2 Connects to the default chargen service port
- 3 Connects to the default echo service port
- 4 Finger Socket
- 5 Get Socket Information
- 6 Multicast Sender
- 7 Multicast Sniffer
- 8 Use the Daytime TCP and Daytime UDP classes
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);
}
}
}