Lab 2C Primer I/O in Java Sockets Threads More Java Stuffs.
Transcript of Lab 2C Primer I/O in Java Sockets Threads More Java Stuffs.
Lab 2C Primer
I/O in Java
Sockets
Threads
More Java Stuffs
Server Flow
1. Start the server with a port if specified (if not, start the server with a default port of 7000)
2. Create a Polling Socket3. Start the server running “forever” and wait for a client to connect4. Open I/O to client5. When connected, send a message to allow client to know they
are connected6. Accept a request from the client7. Respond to the client’s request8. Client port and I/O are closed* Servers run forever
Input/Output in Java
In Java, there are 2 types of major I/O streams classes we are looking at
– Reader/Writer: ASCII text– Streams: binary
For our assignments, we could either read binary strings and convert them to ASCII or we could simply use the provided writer classes
We will use buffered connections for efficiency and coding elegance
– Buffers allow packets to be sent when a buffer is filled, not on a byte-by-byte basis
– Buffers allow us to send an object to a I/O stream instead of a bit
I/O Classes of Interest
InputStreamReader– Takes an input stream from an I/O port and interprets it as
ASCII OutputStreamReader
– Sends an output stream to an I/O port as ASCII BufferedReader
– Takes in InputStream and adds useful methods and a buffer to the stream
PrintWriter– Takes an OutputStream and adds useful methods and an
output buffer to the stream
Sockets in Java
Socket support is provided through: java.net.*– import java.net.*
We have 2 types of sockets we are interested in: – ServerSocket class– Socket class (client sockets)
ServerSocket
ServerSockets are the sockets used to poll a specific port for incoming connections
Steps to using a ServerSocket1. Create a new ServerSocket object
ServerSocket ss = new ServerSocket(port);
2. Wait until a connection has been received This requires blocking statement until a connection is received
3. Upon receiving a connection request, a new socket must be opened Socket client = ss.accept();
Socket I/O
Provided by the methods Socket.getInputStream() and Socket.getOutputStream()
Can be used in conjunction with any other stream sub-class– E.g. PrintWriter and BufferedReader
Example Code for Socket I/O
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(new OutputStreamWriter(client.getOutputStream()), true);
This could also be accomplished in 2 steps each; e.x.:
InputStreamReader temp = new InputStreamReader(client.getInputStream()));
BufferedReader in = new BufferedReader(temp);
Using Socket I/O
Once BufferedReader and PrintWriter objects are created, they are used with the following methods:– <BufferedReaderObject>.readLine();– <PrintWriterObject>.println(String);
Full Example of Streams
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(new OutputStreamWriter(client.getOutputStream()), true);
in.readLine();out.println(“Hello”);
in.close();out.close();client.close();
Parsing Arguments from the Command Prompt
Arguments from the prompt are passed into your main method through the string array args
args[] is an array of space separated Strings– Strings are stored in the array from the leftmost argument to
the rightmost– Since each element of args is type String, you can’t directly
pass that value into your server for use– Java has built in functions for converting data types
To convert from String to Int, the method to use is:Integer.parseInt(String)
String Parsing
Can’t test for String equality with if (string == “hello”)
Methods provided by Java to do String comparisons– String.equals(String) case sensitive– String.equalsIgnoreCase(String) case insensitive
Try/Catch Statements
Exceptions are a java element used for troubleshooting and catching conditions that could “break” a program– e.x.: null-pointer exceptions, passing the wrong data
type, etc. Useful around any code block with I/O, as
that’s where mistakes can be made– The Java compiler enforces try/catch blocks in
newer versions by default
Try/Catch Statements
Idea is: first you try to execute some code– If it fails you get an exception instead of the program
crashing Code in the catch block allows you to keep running the
program, but deal with the error
– If it works you simply exit the try portion and continue executing the program
Try/Catch Example
BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in));
int string;
try {
string = keyIn.readLine();
System.out.print(string);
} catch (Exception e) {
System.out.print(“That wasn’t in Integer!”);
}
Exception Types
Different classes and methods throw different exception types– e.x.: PrintWriter(String, String) throws
FileNotFoundException and UnsupportedEncodingException
Can catch specific exceptions and execute different code based on them
Can catch all exceptions simply with “catch (Exception e)”
Using Exceptions in Lab 2
You can use exceptions to parse the argument entered for the port
You should wrap your server’s executable code itself either in a single or series of try statements to ensure it won’t crash– If it does, you should catch the exception and alert
the system that the server crashed
Other Useful Classes
Classes that have date objects– java.util.Calendar– java.util.Date (partially depreciated)– java.text.simpleDateFormat
Hints
You can either try parsing the first argument of args in main and passing in a port by hand into the server object;
OR You can use 2 constructors for both cases (argument
passed in and no argument) Use the Java API document if you aren’t sure what you
need or how to manipulate and object I don’t care if you use depreciated Date types in this
assignment
Hints
Look through the java.net.* and java.io.* packages – Focus on SocketServer, Socket (and .accept()),
BufferedReader, and BufferedWriter
Look at the simpleDateFormat and Date classes
Lab 2 Protocol-Code Structure
getHead(): StringBuffer– Easy: Loops through receiving data and appending
it into a StringBuffer until the end of the header section is found
What must be added to each line?
getMethod(): String– This parses the method out of the request.– Easy to do, due to location of method in the
Request
Lab 2 Protocol-Code Structure
getLenth(StringBuffer): int– Why is this needed?– Finds a String representing a number, parses it and
returns it
getBody(int): StringBuffer– Uses a Integer to specify how many characters to
read– Must cast each byte you read() as a (char)
getLength()
Use String.indexOf(String) to find what you are looking for:String temp = new String(“This is a test String for index”);int i = temp.indexOf(“String”);
i = 16
Now you know the start of the header you are looking for, but how do you find the value?
– Use a loop and iterate through with temp.charAt(i) until you find the end of the line as a character
– Use substring to parse only the section of string you want– Use the same Integer.parseInt used in Assignment 1
getLength()
//Find “for”
int j;
String temp = new String(“This is a test String for index”);
int i = temp.indexOf(“String”);
for(j=i+7;;j++){
if (!(temp.charAt(i)==' ')) j++;
else break;
}
String answer = temp.substring(i+7, j);
Why do we need the +7 for the index (i+7)?
getBody()
StringBuffer temp = new StringBuffer("");for(i=0;i<length;i++){
temp.append((char)netIn.read());
}
Why do we have to cast the input as (char)? Why can’t we use readLine()?
Threads
We know a processor can only execute one program at a time– One process may run at a time– To run multiple programs (processes), the CPU
must run one for a certain amount of time, save the state of the program, load another executing program and so on
One program can have multiple modules that need to be execute “at the same time” for different functions.– THREADS!
Threads
A parent process can spawn children– A child must complete before parent regains control:
except it can open more children Like a stack, threads only communicate with
their children or parents (sequential) Threads are treated like independent
processes– Each thread gets a slice of the processor/resources
Warning: when different threads access same resources, must ensure they don’t corrupt data.– Who gets to read/write from/to a file?
Threads - Example
Outlook Express
TCP/IP StackRoutines
GUIPOP, IMAPProtocol
I/O Routines
Disk I/O
Using Threads in Java
There are 2 ways– Implement Interface Runnable()– Extend Class Thread()
We will implement Runnable(). Why?– You can only extend a class once in your
hierarchy, but can implement as many Interfaces as you want
Threading in Java – Running Class
public class ThreadTest implements Runnable{
public ThreadTest() {
…
}
Public void run() {
…
}
}
Threading in Java – Calling Class
public void run(){
ServerSocket ss = new ServerSocket(port);
ThreadTest client = new ThreadTest(ss.accept());
Thread t = new Thread(client);
t.start();
}
Java Items for Lab 2
StringBuffer (java.lang.StringBuffer)– .append() takes a string and keeps appending it to the end of
the StringBuffer– Useful for appending a sequence of input together– Cast it to a String to do comparisons
Socket.get*()– This assignment expects you to be able to get information
about your connection. Look over Socket.get<method>() in the API to see what information is available for you to receive.
String.startsWith(String)– Used to test if a String begins with a certain sub-string
Items for Lab 2
String parsing– All commands should be case-insensitive– Actual input should not be directly type-cast (forced
to upper or lower case), or else the message inputted with lose the intended case
– String.equals(), String.equalsIgnoreCase() Can use equals() if you type-cast temporary input string to
compare and keep original untouched
Remember: In HTTP headers are separated from body data with a blank line.