CS 580 Client-Server Programming Fall Semester, 2002 Server Intro |
||
---|---|---|
© 2002, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 26-Sep-02 |
Reading AssignmentJava Java Network Programming, Harold
Basic Network Concepts, Chapter 2
What is a Server?
Server
while (true) { Wait for an incoming request; Perform whatever actions are requested; }
Example - Echo Server
| server | server := SocketAccessor newTCPserverAtPort: 9009. server listenFor: 5. [ | acceptedSocket | "wait for a new connection" acceptedSocket := server accept. "fork off processing of the new stream socket" [ | stream char | stream := acceptedSocket readAppendStream. stream lineEndTransparent. [ (char := stream next) isNil ] whileFalse: [ stream nextPut: char; commit ]. stream close. ] forkAt: Processor userSchedulingPriority -1. ] repeat.
Some Basic Server Issues
Sockets
Streams verses Buffers
Both Java & Smalltalk provide access to socket data via
Java TCP Sockets
Main Classes ServerSocket
public ServerSocket(int port) //port = 0 gives random port public ServerSocket(int port, int backlog) public ServerSocket(int port, int backlog, InetAddress bindAddress)public Socket accept() throws IOException
public InputStream getInputStream() throws IOException public OutputStream getOutputStream() throws IOException
A Simple Date Server
import java.net.Socket; import java.net.ServerSocket; import java.io.*; import java.util.Date; class SimpleDateServer {
public static void main(String[] args) throws IOException { ServerSocket acceptor = new ServerSocket(0); System.out.println("On port " + acceptor.getLocalPort()); while (true) { Socket client = acceptor.accept(); processRequest( client.getInputStream(), client.getOutputStream()); client.close(); } }
(Why "new ServerSocket(0)"?)
Processing Client Request
static void processRequest(InputStream in,OutputStream out) throws IOException { BufferedReader parsedInput = new BufferedReader(new InputStreamReader(in)); // the "true" is to get autoflushing: PrintWriter parsedOutput = new PrintWriter(out,true); String inputLine = parsedInput.readLine(); if (inputLine.startsWith("date")) { Date now = new Date(); parsedOutput.println(now.toString()); } } }
Note: This server is just a first example. It needs a lot of work. We will be working on improving it in later lectures.
Running the Server
Sample run of SimpleDateServer.
(I typed everything appearing in bold font here.)
rohan 16-> java SimpleDateServer &
[1] 16269
On port 62047
rohan 17-> telnet rohan 62047
Trying 130.191.3.100...
Connected to rohan.sdsu.edu.
Escape character is '^]'.
date today
Mon Sep 04 13:37:30 PDT 2000
Connection closed by foreign host.
rohan 18-> telnet rohan 62047
Trying 130.191.3.100...
Connected to rohan.sdsu.edu.
Escape character is '^]'.
time
Connection closed by foreign host.
In this class, shut things down:
rohan 19-> fg
java SimpleDateServer
^C
Warning About telnet Usage
Using telnet to interact with a server is
Smalltalk TCP Sockets
Main Classes
IPSocketAddress
newTCP “selects random port” newTCPserverAtPort: portNumber
accept Wait for a client connection and return it acceptNonBlock return any waiting client connection, return nil if no waiting client connections readAppendStream readStream writeStream Return a stream of the given type on the conection
A Simple Date Server
Smalltalk defineClass: #SimpleDateServer superclass: #{Core.Object} indexedType: #none private: false instanceVariableNames: 'serverSocket ' classInstanceVariableNames: '' imports: '' category: 'SimpleServer'
SimpleDateServer class methodsFor: 'instance creation'
port: anInteger ^super new setPort: anInteger
SimpleDateServer instance methods setPort: anInteger serverSocket := SocketAccessor newTCPserverAtPort: anInteger. serverSocket listenFor: 4; soReuseaddr: true
run | childSocket clientConnection clientIOStream | [childSocket := serverSocket accept. clientIOStream := childSocket readAppendStream. clientIOStream lineEndTransparent. self processRequestOn: clientIOStream.] repeat
processRequestOn: anReadAppendStream | clientRequest | clientRequest := anReadAppendStream through: Character cr. (clientRequest startsWith: 'date') ifTrue: [anReadAppendStream nextPutAll: Time dateAndTimeNow printString]. anReadAppendStream closeRunning the Server
server := SimpleDateServer port: 5556. serverProcess := [server run] fork
Simple Server Issues
Client A builds connection to server, Client A goes to lunch Client B builds connection to server and ... :-(
Backlog
TCP accepts connections before the server is ready
TCP keeps a backlog queue of connections server has not accepted
Java ServerSocket constructor
SocketAccessor>>listenFor: aNumber
Multi-homed Machines
Some machines have two or more physical network interface
public ServerSocket(int port)
public ServerSocket(int port, int backlog, InetAddress bindAddress)
Reusing a Port
Closing TCP connections can remain for several minutes
TCP may block use of the port until the connection is gone
This can be annoying in development
SocketAccessor>> soReuseaddr: true
ServerSocket method setReuseAddress(boolean on)
Allows the port to be resued
End of Line
Platform |
End
of Line Convention
|
Unix |
Line
Feed (LF)
|
Macintosh |
Carriage
return (CR)
|
Windows |
CR-LF |
End of Line & Smalltalk
Java and Smalltalk programs run on all major platforms
Smalltalk assumes files use platform’s end of line convention
Smalltalk input streams convert platforms end of line to CR
Smalltalk output streams convert CR to platform’s end of line
This makes writing cross platform programs easier
Don’t want this to happen socket streams
BufferedExternalStream>> lineEndTransparent
Turns off converstion between CR & end of line
How does Java handle this?
End of File
On a stream connected to a socket
End of file indicates that the connection has been closed!
Don’t use end of file to determine when other end is done talking!
End of Message
How do we know when we are at the end of a message?
BufferedReader parsedInput = new BufferedReader(new InputStreamReader(in));
char[] message = new char[500]; int sizeRead = parsedInput.read(message, 0, 500);If
End of Message
A good client-server protocol specifies
Buffers
Java & Smalltalk streams are buffered
TCP buffers output before sending
A server cannot read bytes left in a client’s buffer
ExternalStream>>commit
Sends data in stream to OS
PrintWriter flush();
Copyright ©, All rights reserved.
2002 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.
Previous    visitors since 26-Sep-02    Next