Escolar Documentos
Profissional Documentos
Cultura Documentos
Applications
Sockets Programming in Java
A socket is one end-point of a two-way communication link between two programs
running on the network. These two programs form a Client/Server application.
In Client/Server applications the server normally listens to a specific port waiting for
connection requests from a client. When a connection request arrives, the client and
the server establish a dedicated connection over which they can communicate. During
the connection process, the client is assigned a local port number, and binds a socket
to it. The client talks to the server by writing to the socket and gets information from
the server by reading from it. Similarly, the server gets a new local port number to
communicate with the client. The server also binds a socket to its local port and
communicates with the client by reading from and writing to it. The server can not use
its specific port to comunicate with the client since it is dedicated only to listen for
connection requests from other clients.
The client and the server must agree on a protocol, that is, they must agree on the
language of the information transferred back and forth through the socket.
The java.net package in the Java development environment provides a class Socket
which implements the client side and the class ServerSocket class which implements
the server side of the two-way link.
There are two communication protocols that one can use for socket programming:
stream communication and dram communication.
TCP is useful for implementing network services, such as remote login (rlogin, telnet)
and file transfer (FTP) -- which require data of indefinite length to be transferred.
UDP is less complex and is often used in implementing client/server applications in
distributed systems built over local area networks.
This document we will show how to program sockets in Java using the TCP/IP
protocol.
Opening a socket
If you are programming a client, then you would open a socket like this:
Socket MyClient;
MyClient = new Socket("Machine name", PortNumber);
or using the exception handling,
Socket MyClient;
try {
MyClient = new Socket("Machine name", PortNumber);
}
catch (IOException e) {
System.out.println(e);
}
Where Machine name is the machine you are trying to open a connection to, and
PortNumber is the port (a number) on which the server you are trying to connect to is
running. When selecting a port number, you should note that port numbers between 0
and 1023 are reserved are reserved for standard services, such as email, FTP, and
HTTP.
If you are programming a server, then this is how you open a socket:
ServerSocket MyService;
try {
MyServerice = new ServerSocket(PortNumber);
}
catch (IOException e) {
System.out.println(e);
}
When implementing a server you also need to create a socket object from the
ServerSocket in order to listen for and accept connections from clients.
Socket clientSocket = null;
try {
serviceSocket = MyService.accept();
}
catch (IOException e) {
System.out.println(e);
}
On the server side, you can use DataInputStream to receive input from the client:
DataInputStream input;
try {
input = new DataInputStream(serviceSocket.getInputStream());
}
catch (IOException e) {
System.out.println(e);
}
On the client side, you can create an output stream to send information to the server
socket using the class PrintStream or DataOutputStream of java.io:
PrintStream output;
try {
output = new PrintStream(MyClient.getOutputStream());
}
catch (IOException e) {
System.out.println(e);
}
The class PrintStream has methods for displaying textual representation of Java
primitive data types. Its Write and println methods are important here. Also, you may
want to use the DataOutputStream:
DataOutputStream output;
try {
output = new DataOutputStream(MyClient.getOutputStream());
}
catch (IOException e) {
System.out.println(e);
}
The class DataOutputStream allows you to write Java primitive data types; many of
its methods write a single Java primitive type to the output stream. The method
writeBytes is a useful one.
On the server side, you can use the class PrintStream to send information to the client.
PrintStream output;
try {
output = new PrintStream(serviceSocket.getOutputStream());
}
catch (IOException e) {
System.out.println(e);
}
Closing sockets
You should always close the output and input stream before you close the socket. On
the client side:
try {
output.close();
input.close();
MyClient.close();
}
catch (IOException e) {
System.out.println(e);
}
On the server side:
try {
output.close();
input.close();
serviceSocket.close();
MyService.close();
}
catch (IOException e) {
System.out.println(e);
}
This is a simple client which reads from the standard input a line and sends it to the
echo server. It keeps then reading from the socket till it receives the "Ok" from the
server. Once it received that then it breaks.
//Example 23
import java.io.*;
import java.net.*;
// declaration section:
// clientClient: our client socket
// os: output stream
// is: input stream
// Initialization section:
// Try to open a socket on port 2222
// Try to open input and output streams
try {
clientSocket = new Socket("ti.utm.md", 2222);
os = new PrintStream(clientSocket.getOutputStream());
is = new DataInputStream(clientSocket.getInputStream());
inputLine = new DataInputStream(new
BufferedInputStream(System.in));
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection
to host");
}
// keep on reading from/to the socket till we receive the "Ok" from
the server,
// once we received that then we want to break.
String responseLine;
os.println(inputLine.readLine());
while ((responseLine = is.readLine()) != null) {
System.out.println(responseLine);
if (responseLine.indexOf("Ok") != -1) {
break;
}
os.println(inputLine.readLine());
}
// clean up:
// close the output stream
// close the input stream
// close the socket
os.close();
is.close();
clientSocket.close();
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown
host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
}
The server
This is a simple echo server. As long as it receives data it echos that data back to the
client appending them to the "From server :" string.
//Example 24
import java.io.*;
import java.net.*;
// declaration section:
// declare a server socket and a client socket for the server
// declare an input and an output stream
try {
echoServer = new ServerSocket(2222);
}
catch (IOException e) {
System.out.println(e);
}
try {
clientSocket = echoServer.accept();
is = new DataInputStream(clientSocket.getInputStream());
os = new PrintStream(clientSocket.getOutputStream());
while (true) {
line = is.readLine();
os.println("From server: "+ line);
}
}
catch (IOException e) {
System.out.println(e);
}
}
}
import java.io.*;
import java.net.*;
// Declaration section
// clientClient: the client socket
// os: the output stream
// is: the input stream
int port_number=2222;
String host="localhost";
if (args.length < 2)
{
System.out.println("Usage: java MultiThreadChatClient
\n"+
"Now using host="+host+",
port_number="+port_number);
} else {
host=args[0];
port_number=Integer.valueOf(args[1]).intValue();
}
// Initialization section:
// Try to open a socket on a given host and port
// Try to open input and output streams
try {
clientSocket = new Socket(host, port_number);
inputLine = new BufferedReader(new
InputStreamReader(System.in));
os = new PrintStream(clientSocket.getOutputStream());
is = new DataInputStream(clientSocket.getInputStream());
} catch (UnknownHostException e) {
System.err.println("Don't know about host "+host);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection
to the host "+host);
}
while (!closed) {
os.println(inputLine.readLine());
}
// Clean up:
// close the output stream
// close the input stream
// close the socket
os.close();
is.close();
clientSocket.close();
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
This is a multithreaded chat server. It uses a separate thread for every client. It spawns
a new client thread every time a new connection from a client is established. This
client thread opens the input and the output streams for a particular client, ask the
client's name, informs all the clients currently connected to the server about the fact
that a new client has joined the chat room, and as long as it receive data, echos that
data back to all other clients. When the client leaves the chat room this thread informs
also all the clients about that and terminates.
//Example 26
import java.io.*;
import java.net.*;
// Declaration section:
// declare a server socket and a client socket for the server
// declare an input and an output stream
int port_number=2222;
if (args.length < 1)
{
System.out.println("Usage: java MultiThreadChatServer
\n"+
"Now using port
number="+port_number);
} else {
port_number=Integer.valueOf(args[0]).intValue();
}
// Initialization section:
// Try to open a server socket on port port_number (default
2222)
// Note that we can't choose a port less than 1023 if we are
not
// privileged users (root)
try {
serverSocket = new ServerSocket(port_number);
}
catch (IOException e)
{System.out.println(e);}
while(true){
try {
clientSocket = serverSocket.accept();
for(int i=0; i<=9; i++){
if(t[i]==null)
{
(t[i] = new
clientThread(clientSocket,t)).start();
break;
}
}
}
catch (IOException e) {
System.out.println(e);}
}
}
}
// This client thread opens the input and the output streams for a
particular client,
// ask the client's name, informs all the clients currently connected
to the
// server about the fact that a new client has joined the chat room,
// and as long as it receive data, echos that data back to all other
clients.
// When the client leaves the chat room this thread informs also all
the
// clients about that and terminates.
DataInputStream is = null;
PrintStream os = null;
Socket clientSocket = null;
clientThread t[];
// Clean up:
// Set to null the current thread variable such that
other client could
// be accepted by the server
for(int i=0; i<=9; i++)
if (t[i]==this) t[i]=null;
is.close();
os.close();
clientSocket.close();
}
catch(IOException e){};
}
}
Conclusion
Sockets allows to implement Client/Socket applications and provide a powerful and
flexibile infrastructure for network programming. There are some other classes fot
network programming. If you are trying to connect to the World Wide Web, the URL
class and related classes (URLConnection, URLEncoder) are probably more suitable
than the socket classes to what you are doing. In fact, URLs are a relatively high level
connection to the Web and use sockets as part of the underlying implementation.
Exercises
1. Study and try all the examples presented above.
2. Modify the the multithreaded chat example such that the server can accept an
unlimited number of clients.