150 likes | 156 Views
Learn about sockets, ports, and protocols for communication across networks. Explore server-side programming with an example.
E N D
Java Server Programming Web Interface for Java Programs
Introduction to Sockets • What is a socket • In the most simple view a socket is a way for programs to communicate across a network. For this to work we need to know some information. • There are 2 main things we need to know for this simple socket. • We need to know the name or address of the other computer. With that information we should be able to find it on the network. • We need to know what type of network we are talking across. Here we are going to talk about TCP/IP. With the success of the internet TCP/IP is the most prevalent protocol in use today. • Can sockets be used to talk to different programs on the same computer? • The answer is yes and we will go into more information later about that. Introduction
Sockets - a more In-Depth Look • More Information Needed • So a question that might occur to me from the simple view is can there be more then one program waiting for a socket on a computer at a time, and if so how can we distinguish them. • That leads us to Ports • Ports are very simple. They are a way to distinguish which program on a computer that you want to talk to. • Some ports are reserved - the operating system says that any port under 3000 can only be listened to by a program I know about. This was for security reasons but proved in-effective. It is still around because of tradition. • So what information do we need to talk to a computer on the network? • The type of Network - TCP/IP • The computer Name or Address • The Port of the program Introduction
Two sides of a Socket • Sockets have 2 sides • First is the side that is listening. Listening means that it is waiting for some other program to talk to it. In a client - server model, the end that is listening is called the server. • The other end is the program making the connection. This end is referred to as the client. This end does all the work to set up the socket between the programs. It must know the address of the server and which port it is listening on. • Once the connection is made both ends look exactly the same and information can pass both ways. Later we will talk about how the programs communicate. Introduction
How do the programs communicate • Now that we have this connection between the 2 computers how do they talk to each other? • Both programs need to come to an agreement. This agreement is called a protocol. • Protocols vary from simple to complex. • Simple protocol - send the number of bytes you are going to send then each byte. • Complex protocol usually is contained within a simple protocol. An example would be to send a command followed by some parameters. When the server receives the command it will respond back with the results of the command then the client will respond back acknowledging the results were received. Introduction
A Simple Example: Server Side import java.net.*; import java.io.*; public class SimpleServer extends Thread { private ServerSocket listenSocket; public int listenPort = 6000; public String filename = "MyFile.txt"; Introduction
public void run() { String input; Socket sock; PrintWriter fileOutput; PrintWriter socketOutput; BufferedReader socketInput; try { System.out.println("Setting up Server socket"); listenSocket = new ServerSocket(listenPort); while(true) { try { System.out.println("Listening for connection"); sock = listenSocket.accept(); System.out.println("We have a connection"); // We are only going to be getting strings so we will use a buffered input stream. // They will send us 1 line of text and we will appended it to the file. socketInput = new BufferedReader( new InputStreamReader( sock.getInputStream())); Introduction
socketOutput = new PrintWriter( sock.getOutputStream()); fileOutput = new PrintWriter( new FileWriter(filename, true)); System.out.println("Opened file"); // Read a line until there are no more left. Add them to the file. input = socketInput.readLine(); while(input != null) { System.out.println("Input: " + input); fileOutput.println( input ); input = socketInput.readLine(); } fileOutput.flush(); fileOutput.close(); sock.close(); System.out.println("closed file and socket"); } catch(Exception e) { System.out.println("Exception: " + e); sock = null; System.gc(); } } } catch(IOException e) { System.out.println("Unable to open socket: " + e); } } Introduction
public static void main(String args[]) { SimpleServer s = new SimpleServer(); s.setDaemon(false); try { if(args.length > 2) throw new Exception("Wrong number of arguments"); if(args.length > 0) { s.listenPort = Integer.valueOf(args[0]).intValue(); } if(args.length > 1) { s.filename = args[1]; } s.start(); } catch(Exception e) { } } } Introduction
Understanding the Code: Server Side First we make our server class extend Thread., allowing us to start the server and return from the function call. We would then have our server running in the background. Making a thread in JAVA is easy. You inherit from the class Thread, then you make a function called run that describes what you want the thread to do. Next we set up some things for are server. The most important one to note is the port. We store this in a variable to allow us to change it’s value at run time. A ServerSocket is a class that can listen on a port and accept incoming connections. When we create the instance of the ServerSocket (we use the new operator), we give it a port number that it binds to. If this port is already in use an exception will be thrown. Java requires us to catch any possible thrown exceptions hence the try / catch surrounding the main body of the code. Well we are bound to the port and ready to get connections and our server wants to do this over and over again. So we go into an infinite loop, requiring the operating system to shut us down at the appropriate time. Then we accept a connection. What happens when we accept a connection is that we wait until someone else connects to the port we are listening on, on this server of course. We are just sitting there waiting unable to do any other work. This is important to remember for when our server gets a little more advanced. Now a client connects to us. When this happens we get a socket. This socket is how all information will be passed back and forth between the client and the server. Sockets send bytes across them to the other server. This can be tedious when working with strings. Java allows us to use the Output stream of a socket in any manner we wish. Introduction
Understanding the Code: Server Side … cont Next we get the Output stream from the socket and create a PrintWriter from it. PrintWriters send text very well and make it simple to pass text messages back and forth. If we were going to be sending an image this would not be a good choice. We do something similar with the input stream, creating a BufferedReader. BufferedReaders allow us to read a line of text from a stream. That is exactly what we need for this example. In general most things are sent as text across the net because it is convenient and easy to debug. Unfortunately because of those traits it is also very insecure and sometimes slow. Our example now opens a file that it will append incoming information to. We receive 1 line of text at a time writing it out to the file. When we get an empty line we close the connection and the file and go back to listing for a new connection. Lastly we have a simple main that will take a port and filename both optional set those parameters in the Server and start it going. Introduction
Simple Example: Client Side import java.net.*; import java.io.*; public class SimpleClient { private String serverName; private int serverPort; private Socket socket; public void sendMessage() { String message; PrintWriter socketOutput; BufferedReader socketInput; BufferedReader inReader; try { socket = new Socket(serverName, serverPort); socketOutput = new PrintWriter(socket.getOutputStream()); socketInput = new BufferedReader( new InputStreamReader( socket.getInputStream())); inReader = new BufferedReader( new InputStreamReader(System.in)); Introduction
System.out.println("Enter Message to be Sent. Enter a blank line when done."); message = inReader.readLine().trim(); while(message.equals("") == false) { socketOutput.println(message); socketOutput.flush(); message = inReader.readLine().trim(); } socket.getOutputStream().close(); socket.close(); } catch(UnknownHostException uhe) { System.out.println("Unknown Server Name: " + serverName); } catch(IOException ioe) { System.out.println("Unable to send string: " + ioe); } } public SimpleClient(String serverName, int serverPort) { this.serverName = serverName; this.serverPort = serverPort; } Introduction
public static void main(String args[]) { SimpleClient sc; if( args.length != 2) { System.err.println("Invalid Usage: SimpleClient servername serverport"); System.exit(1); } sc = new SimpleClient(args[0], Integer.valueOf(args[1]).intValue()); sc.sendMessage(); } } Introduction
Understanding the Code: Client Side Unlike servers the client needs more information to get the connection going. The most important pieces of information are the address of the server and the port number it is listening to. With out that all else is moot. Our simple example connects to the server, sends several lines of text the disconnects. Main passes the information to our client application and calls sendMessage. sendMessage attempts to connect to the server. If this fails an exception will be thrown that must be handled. Like the server we use the input / output streams as BufferedReader / PrintWriter accordingly. We then prompt the user to enter text. We read each line and send it to the server. When they type a blank line we close the output stream so the server knows that no more information will be coming. The server closes the connection and we are done. Introduction