690 likes | 713 Views
Practical guide for programmers. Learn basic Java operations, socket introduction, building Java applications, and using Java IDEs. Includes sample Java applications and client/server communication concepts in Java.
E N D
Intro to Java C/S TCP/IP Sockets in Java Practical guide for programmers Kenneth and Michael
outline • 1. Basic Java operation • 2. Java Socket Introduction
JAVA Implementation Java program Java program Java program Java program Java Cmds Java Cmds Java Cmds VM VM VM SPARC PowerPC Intel
Operations Environments • Applications program (~DOS window) • supports file access • Applet (browser) – no longer generally supported • supports Internet linkages.
Building Java Applications Using Java Development Kit • Get a copy of the JDK (www.oracle.com, etc.) • Install the development kit (tools and classes) • Create MyApp.java source file • text editor (notepad, etc.) • winedit, Café, etc. • Compile .java file to create .class file • javac MyApp.java • Run application (.class file) through java VM • java MyApp
Building Java Applications Using Java IDEs • NetBeans • Available from netbeans.org • Eclipse • Available from www.eclipse.org • jCreator le • available from jcreator.com • jcreator pro – academic license $35 • jDeveloper • available from www.oracle.com/technetwork/developer-tools/jdev • many others
Sample Java App G:\Data\Java\MyHelloApp>type MyHelloApp.java class MyHelloApp { public static void main (String argv[]) { String message[] = new String[2]; message[0] = "Welcome to CS423"; message[1] = "The subject is JAVA!"; System.out.println (message[0]); System.out.println (message[1]); } }
MyHelloApp Implementation MyHelloApp.java Java compiler MyHelloApp.class MyHelloApp.class Java byte code VM machine code
Sample Java App G:\Data\Java\MyHelloApp>javac MyHelloApp.java G:\Data\Java\MyHelloApp>java MyHelloApp Welcome to CS423 The subject is JAVA! G:\Data\Java\MyHelloApp>
Get Input from User import java.io.*; class InputApp { InputApp () { DataInputStream dis = new DataInputStream (System.in); String sIn = " "; String sOut = " "; File fIn; File fOut; FileInputStream fis; FileOutputStream fos; int iNumBytesRead; byte[] ab;
Get Input from User System.out.println ("*-------------------------------------------*"); System.out.print ("Enter Source File Name Here: "); System.out.flush (); try {sIn = dis.readLine ();} catch (Exception e) {System.out.println ("Exception on input file name" + e);} System.out.print("Enter Destination File Name Here: "); System.out.flush (); try {sOut = dis.readLine ();} catch (Exception e) {System.out.println ("Exception on output file name" + e);}
Get Input from User try { fIn = new File (sIn); fis = new FileInputStream (fIn); fOut = new File (sOut); fos = new FileOutputStream (fOut); ab = new byte[2048]; while ((iNumBytesRead = fis.read (ab)) != -1) { fos.write (ab, 0, iNumBytesRead); } fis.close (); fos.close (); } catch (Exception e) {System.out.println ("Exception during copy: " + e); }
Get Input from User System.out.println ("Data copied from " + sIn + " to " + sOut); System.out.println ("*-------------------------------------------*"); } public static void main (String args[]) { new InputApp (); } }
Get Input from User G:\Data\Java\InputApp>java InputApp *-------------------------------------------* Enter Source File Name Here: books_db.txt Enter Destination File Name Here: My_list.txt Data copied from books_db.txt to My_list.txt *-------------------------------------------* G:\Data\Java\InputApp>
Passing Data to Programs publicclassParmApplication { publicstaticvoid main(String argv[]){ for (inti=0; i < argv.length; i++){ System.out.println(i + ": " + argv[i]); } } } $ javac ParmApplication.java $ java ParmApplication 1 2 3 0: 1 1: 2 2: 3
Client / Server in Java • Primary communications is through sockets. • (Web type access also available through URL class) • Browser security limits the access that a program can have when run as an applet. Lots of security problems.. So.. applets are no longer supported in HTML5. • Graphical applications supported with new methods and IDEs. • “Default” socket is stream (TCP). • Socket classes implemented in java.net package
Basic Sockets Classes • Socket • ServerSocket • SocketAddress • InetAddress • Datagram Socket • Datagram Packet • Multicast Socket • URL
Socket Client/Server in Java • Typically client used to be applet, but can be graphical application or command line • Server is written as java application or even in some other language (c, c++, etc.). • Where client access is through the Web , the server must be running on the web server machine.
Find your IP address • InetAddress abstraction represents a network destination, including domain names and numerical address info. • Inet4Address • Inet6Address
InetAddressExample import java.util.Enumeration; import java.net.*; public class InetAddressExample { public static void main(String[] args) { Enumeration<NetworkInterface> interfaceList = NetworkInterface.getNetworkInterfaces(); while (interfaceList.hasMoreElements()) { NetworkInterface iface = interfaceList.nextElement(); System.out.println("Interface " + iface.getName() + ":"); Enumeration<InetAddress> addrList = iface.getInetAddresses(); if (!addrList.hasMoreElements()) { System.out.println("\t(No addresses for this interface)"); } while (addrList.hasMoreElements()) { InetAddress address = addrList.nextElement(); System.out.print("\tAddress " + ((address instanceof Inet4Address ? "(v4)" : (address instanceof Inet6Address ? "(v6)" : "(?)")))); System.out.println(": " + address.getHostAddress()); } }
InetAddressExample // Get name(s)/address(es) of hosts given on command line for (String host : args) { try { System.out.println(host + ":"); InetAddress[] addressList = InetAddress.getAllByName(host); for (InetAddress address : addressList) { System.out.println("\t" + address.getHostName() + "/" + address.getHostAddress()); } } catch (UnknownHostException e) { System.out.println("\tUnable to find address for " + host); } } } }
InetAddressExample Interface awdl0: Address (v6): fe80:0:0:0:10b0:4dff:fef0:85d0%8 Interface vboxnet0: Address (v4): 192.168.56.1 Interface en0: Address (v6): 2605:6000:3814:8000:7d14:414:7e03:49a8 Address (v6): 2605:6000:3814:8000:62f8:1dff:feab:9414 Address (v6): fe80:0:0:0:62f8:1dff:feab:9414%4 Address (v4): 10.0.1.23 Interface lo0: Address (v6): fe80:0:0:0:0:0:0:1%1 Address (v6): 0:0:0:0:0:0:0:1 Address (v4): 127.0.0.1 www.umkc.edu: www.umkc.edu/134.193.116.82 www.umkc.edu/2610:e0:a040:64a2:0:0:0:52
More about InetAddress • Static InetAddress[] getAllbyName(String host) • Static InetAddressgetByName(String host) • Static InetAddressgetLocalHost()
TCP Socket • Java provides two classes for TCP • Socket for client • ServerSocket for server • //headers import java.net.Socket; import java.net.SocketException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;
TCP Client • Construct a Socket • A connected Socket contains an InputStream and OutputStream that can be just for data input and output • Close()
A TCPEchoClient Example public class TCPEchoClient { public static void main(String[] args) throws IOException { if ((args.length < 2) || (args.length > 3)) // Test for correct # of args throw new IllegalArgumentException("Parameter(s): <Server> <Word> [<Port>]"); String server = args[0]; // Server name or IP address // Convert argument String to bytes using the default character encoding byte[] data = args[1].getBytes(); int servPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7; // Create socket that is connected to server on specified port Socket socket = new Socket(server, servPort); System.out.println("Connected to server...sending echo string"); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); out.write(data); // Send the encoded string to the server // Receive the same string back from the server int totalBytesRcvd = 0; // Total bytes received so far int bytesRcvd; // Bytes received in last read while (totalBytesRcvd < data.length) { if ((bytesRcvd = in.read(data, totalBytesRcvd, data.length - totalBytesRcvd)) == -1) throw new SocketException("Connection closed prematurely"); totalBytesRcvd += bytesRcvd; } // data array is full System.out.println("Received: " + new String(data)); socket.close(); // Close the socket and its streams } }
Socket() constructors • Socket(InetAddress remoteAddr, int remotePort) • Socket(String remoteHost, int RemotePort) • Socket(InetAddress remoteAddr, int remotePort, InetAddress LocalAddress, int Localport) • Socket(String remoteHost, int remotePort, InetAddress localAddress, int localport) • Socket() • Then you can to call connect()
TCP Server • ServerSocket() • accpet() • A connected Socket contains an InputStream and OutputStream that can be just for data input and output • Close()
A TCPEchoServer Example import java.net.*; // for Socket, ServerSocket, and InetAddress import java.io.*; // for IOException and Input/OutputStream public class TCPEchoServer { private static final int BUFSIZE = 32; // Size of receive buffer public static void main(String[] args) throws IOException { if (args.length != 1) // Test for correct # of args throw new IllegalArgumentException("Parameter(s): <Port>"); int servPort = Integer.parseInt(args[0]); // Create a server socket to accept client connection requests ServerSocket servSock = new ServerSocket(servPort); int recvMsgSize; // Size of received message byte[] receiveBuf = new byte[BUFSIZE]; // Receive buffer while (true) { // Run forever, accepting and servicing connections Socket clntSock = servSock.accept(); // Get client connection SocketAddress clientAddress = clntSock.getRemoteSocketAddress(); System.out.println("Handling client at " + clientAddress); //ip and port number InputStream in = clntSock.getInputStream(); OutputStream out = clntSock.getOutputStream(); // Receive until client closes connection, indicated by -1 return while ((recvMsgSize = in.read(receiveBuf)) != -1) { out.write(receiveBuf, 0, recvMsgSize); } clntSock.close(); // Close the socket. We are done with this client! } /* NOT REACHED */ } }
TCP ServerSocket() constructor • ServerSocket(Int localPort) • ServerSocket(int localport, int queueLimit) • ServerSocket(int localPort, int queueLimit, InetAddress LocalAddress) • ServerSocket() • Then you have to call bind() • void bind(int port)
Java TCP Socket Input and output Stream • OutputStream/Send void write(int data) void write(byte[] data) void write(byte[] data, int offset, int length) void flush() void close() • InputStream/recv int read(byte[] data) int read(byte[] data, int offset, int length)
UDP DatagramPacketUDP data send/recv • DatagramPacket(byte[] buf, int length) • DatagramPacket(byte[] buf, int length, InetAddress address, int port) • DatagramPacket(byte[] buf, int offset, int length) • DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) • DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) • DatagramPacket(byte[] buf, int length, SocketAddress address)
UDP Socket • DatagramSocket • send/receive • close
A UDP Client import java.net.DatagramSocket; import java.net.DatagramPacket; import java.net.InetAddress; import java.io.IOException; import java.io.InterruptedIOException; public class UDPEchoClientTimeout { private static final int TIMEOUT = 3000; // Resend timeout (milliseconds) private static final int MAXTRIES = 5; // Maximum retransmissions public static void main(String[] args) throws IOException { if ((args.length < 2) || (args.length > 3)) { // Test for correct # of args throw new IllegalArgumentException("Parameter(s): <Server> <Word> [<Port>]"); } InetAddress serverAddress = InetAddress.getByName(args[0]); // Server address // Convert the argument String to bytes using the default encoding byte[] bytesToSend = args[1].getBytes(); int servPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7; DatagramSocket socket = new DatagramSocket(); socket.setSoTimeout(TIMEOUT); // Maximum receive blocking time (milliseconds) DatagramPacket sendPacket = new DatagramPacket(bytesToSend, // Sending packet bytesToSend.length, serverAddress, servPort); DatagramPacket receivePacket = // Receiving packet new DatagramPacket(new byte[bytesToSend.length], bytesToSend.length); int tries = 0; // Packets may be lost, so we have to keep trying boolean receivedResponse = false;
A UDP Client do { socket.send(sendPacket); // Send the echo string try { socket.receive(receivePacket); // Attempt echo reply reception if (!receivePacket.getAddress().equals(serverAddress)) {// Check source throw new IOException("Received packet from an unknown source"); } receivedResponse = true; } catch (InterruptedIOException e) { // We did not get anything tries += 1; System.out.println("Timed out, " + (MAXTRIES - tries) + " more tries..."); } } while ((!receivedResponse) && (tries < MAXTRIES)); if (receivedResponse) { System.out.println("Received: " + new String(receivePacket.getData())); } else { System.out.println("No response -- giving up."); } socket.close(); } }
UDP DatagramSocket() constructor • DatagramSocket() • DatagramSocket(int localport) • DatagramSocket(int localport, InetAddress localaddress) • Connect() • void connect(InetAddress remoteAddr, int remotePort)
A UDP Server import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UDPEchoServer { private static final int ECHOMAX = 255; // Maximum size of echo datagram public static void main(String[] args) throws IOException { if (args.length != 1) { // Test for correct argument list throw new IllegalArgumentException("Parameter(s): <Port>"); } int servPort = Integer.parseInt(args[0]); DatagramSocket socket = new DatagramSocket(servPort); DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX], ECHOMAX); while (true) { // Run forever, receiving and echoing datagrams socket.receive(packet); // Receive packet from client System.out.println("Handling client at " + packet.getAddress().getHostAddress() + " on port " + packet.getPort()); socket.send(packet); // Send the same packet back to client packet.setLength(ECHOMAX); // Reset length to avoid shrinking buffer } /* NOT REACHED */ } }
Java multitasking • Iterative server • concurrent server • thread per client
Java Threads import java.util.concurrent.TimeUnit; public class ThreadExample implements Runnable { private String greeting; // Message to print to console public ThreadExample(String greeting) { this.greeting = greeting; } public void run() { while (true) { System.out.println(Thread.currentThread().getName() + ": " + greeting); try { // Sleep 0 to 100 milliseconds TimeUnit.MILLISECONDS.sleep(((long) Math.random() * 100)); } catch (InterruptedException e) { } // Should not happen } } public static void main(String[] args) { new Thread(new ThreadExample("Hello")).start(); new Thread(new ThreadExample("Aloha")).start(); new Thread(new ThreadExample("Ciao")).start(); } }
A Concurrent TCP Server import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.logging.Logger; public class TCPEchoServerThread { public static void main(String[] args) throws IOException { if (args.length != 1) { // Test for correct # of args throw new IllegalArgumentException("Parameter(s): <Port>"); } int echoServPort = Integer.parseInt(args[0]); // Server port // Create a server socket to accept client connection requests ServerSocket servSock = new ServerSocket(echoServPort); // Run forever, accepting and spawning a thread for each connection while (true) { Socket clntSock = servSock.accept(); // Block waiting for connection // Spawn thread to handle new connection Thread thread = new Thread(new ThreadExample(clntSock); thread.start(); } /* NOT REACHED */ } }
NIO – Advanced Java socket programming • New I/O packages • java.nio.channels • Selector • Channel • java.nio • The single-thread approach • Channels: a socket file descriptor, a file or a device • Select():allows you to check “who” is ready to be served • Buffers are another feature of NIO that allows you to access the underlying data from reads and writes to avoid the overhead of copying data into new arrays.
Why NIO? • Make Socket functions Non-blocking • A regular Socket • is a blocking input/output device • A SocketChannel • is a non-blocking way to read from sockets, • use select() method
A TCP Non-blocking Client import java.net.InetSocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; public class TCPEchoClientNonblocking { public static void main(String args[]) throws Exception { if ((args.length < 2) || (args.length > 3)) // Test for correct # of args throw new IllegalArgumentException("Parameter(s): <Server> <Word> [<Port>]"); String server = args[0]; // Server name or IP address // Convert input String to bytes using the default charset byte[] argument = args[1].getBytes(); int servPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7; // Create channel and set to nonblocking SocketChannel clntChan = SocketChannel.open(); clntChan.configureBlocking(false);
A TCP Non-blocking Client // Initiate connection to server and repeatedly poll until complete if (!clntChan.connect(new InetSocketAddress(server, servPort))) { while (!clntChan.finishConnect()) { System.out.print("."); // Do something else } } ByteBuffer writeBuf = ByteBuffer.wrap(argument); ByteBuffer readBuf = ByteBuffer.allocate(argument.length); int totalBytesRcvd = 0; // Total bytes received so far int bytesRcvd; // Bytes received in last read while (totalBytesRcvd < argument.length) { if (writeBuf.hasRemaining()) { clntChan.write(writeBuf); } if ((bytesRcvd = clntChan.read(readBuf)) == -1) { throw new SocketException("Connection closed prematurely"); } totalBytesRcvd += bytesRcvd; System.out.print("."); // Do something else } System.out.println("Received: " + // convert to String per default charset new String(readBuf.array(), 0, totalBytesRcvd)); clntChan.close(); } }
A TCP Server using Select() import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.util.Iterator; public class TCPServerSelector { private static final int BUFSIZE = 256; // Buffer size (bytes) private static final int TIMEOUT = 3000; // Wait timeout (milliseconds) public static void main(String[] args) throws IOException { if (args.length < 1) { // Test for correct # of args throw new IllegalArgumentException("Parameter(s): <Port> ..."); } // Create a selector to multiplex listening sockets and connections Selector selector = Selector.open(); // Create listening socket channel for each port and register selector for (String arg : args) { ServerSocketChannel listnChannel = ServerSocketChannel.open(); listnChannel.socket().bind(new InetSocketAddress(Integer.parseInt(arg))); listnChannel.configureBlocking(false); // must be nonblocking to register // Register selector with channel. The returned key is ignored listnChannel.register(selector, SelectionKey.OP_ACCEPT); }
A TCP Server using Select() while (true) { // Run forever, processing available I/O operations // Wait for some channel to be ready (or timeout) if (selector.select(TIMEOUT) == 0) { // returns # of ready chans System.out.print("."); continue; } // Get iterator on set of keys with I/O to process Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator(); while (keyIter.hasNext()) { SelectionKey key = keyIter.next(); // Key is bit mask // Server socket channel has pending connection requests? if (key.isAcceptable()) { //accpet new connection; } // Client socket channel has pending data? if (key.isReadable()) { //ready to read; } // Client socket channel is available for writing and // key is valid (i.e., channel not closed)? if (key.isValid() && key.isWritable()) { //ready to write } keyIter.remove(); // remove from set of selected keys } } } }
TCP and Buffering • You should never assume any correspondence (return value) between write/send and read/receive • It depends on the buffer and the timing of the transfer of data over the network from sender side TCP implementation to the receiver side of implementation
Sender buffer byte[] buffer0 = new byte[1000]; byte[] buffer1 = new byte[2000]; byte[] buffer2 = new byte[5000]; Socket s = new Socket(destAddr, destPort); OutputStream out = s.getOutputStream(); ... out.write(buffer0); out.write(buffer1); out.write(buffer2);
receiver buffer byte[] buffer0 = new byte[1500]; byte[] buffer1 = new byte[2000]; byte[] buffer2 = new byte[4000]; byte[] buffer3 = new byte[500]; Socket s = new Socket(destAddr, destPort); InputStream in = s.getInputStream(); ... in.read(buffer0); in.read(buffer1); in.read(buffer2); in.read(buffer3);