• No results found

Sockets. Programação de Sockets em Java. Socket Abstractions. Camada de Transporte

N/A
N/A
Protected

Academic year: 2021

Share "Sockets. Programação de Sockets em Java. Socket Abstractions. Camada de Transporte"

Copied!
19
0
0

Loading.... (view fulltext now)

Full text

(1)

Programação de Sockets

em Java

SLIDES_10 SISTEMAS INFORMÁTICOS I, ENG. BIOMÉDICA

Sockets

TCP/UDP IP Ethernet Adapter Server TCP/UDP IP Ethernet Adapter Clients

Socket API

hardware kernel space user space ports

Socket Abstractions

File server Mail server WWW server

Camada de Transporte

UDP: User Datagram Protocol

- no acknowledgements

- no retransmissions

- out of order, duplicates possible

- connectionless

TCP: Transmission Control Protocol

- reliable (in order, all arrive, no duplicates)

- flow control

(2)

Package java.net

• Classes

DatagramPacketDatagramSocketInetAddressServerSocketSocket

• Exceptions

– BindException – ConnectException – MalformedURLException – NoRouteToHostException – ProtocolException – SocketException – UnknownHostException – UnknownServiceException

The java.net

package provides networking

support in java.

InetAddress

- public byte[] getAddress();

- public static InetAddress[] getAllByName(String host);

- public static InetAddress getByName(String host);

- public String getHostName();

- public static InetAddress getLocalHost();

•The

java.net.InetAddress

class represents an IP address.

Exemplo: InetAddress

import java.io.* ;

import java.net.* ; public class InetAddressTest {

public static void main( String args[] ) {

try {

InetAddress myself = InetAddress.getLocalHost();

InetAddress machine = InetAddress.getByName("www.dei.uc.pt"); System.out.println("My name : " + myself.getHostName()); System.out.println("My IP : " + myself.getHostAddress()); System.out.println("UnivSite name : " + machine.getHostName()); System.out.println("UnivSite IP : " + machine.getHostAddress());

} catch (UnknownHostException e) { System.out.println ("Could not find address "); } catch (IOException e) {

System.out.println (e);

Ports

• Port numbers can be:

• Well-known (port 0-1023) • Dynamic or private (port 1024-65535) • Servers/daemons usually use well-known

ports

• Any client can identify the server/service • HTTP = 80, FTP = 21, Telnet = 23, ... • Clients usually use dynamic ports

• Assigned by the kernel at run time • A full address for a socket is then:

IP address + port number ex: student.dei.uc.pt: 8080

TCP/UDP IP Ethernet Adapter

NTP daemon serverWeb

(3)

Stream Sockets (TCP)

TCP service:“reliable” transfer of bytesfrom one process to another

Sockets Stream

• class

Socket

– Connects to a ServerSocket.

• class

ServerSocket

– Accepts requests for socket connections.

– Creates a new Socket for each connection.

Criação de Sockets

• Each Socket object is associated with exactly one remote host. • To connect to a different host, you must create a new Socket object. • You specify the remote host and the port to connect.

• The host may be specified as a string like “eden.dei.uc.pt" or an

InetAddress object.

• The port should be an int between 1 and 65535. Socket s = new Socket(“www.dei.uc.pt",80);

Server and Ports

• On Unix systems (but not Windows) your program must be running as root to bind to a port between 1 and 1023.

• 0 is a special port number. It tells the system to pick on of the available ports.

• Many well known ports – echo 7 – time 13 – ftp 21 – telnet 23 – finger 79 – smpt 25 – http 80

(4)

Clients and Ports

• The client is assigned a port number on the local

machine as part of establishing the connection.

• How to know the number of the local port:

getLocalPort()

• A client can connect to a particular port by using

programs such as telnet, as follows:

telnet www.dei.uc.pt 80

Client/server socket interaction: TCP

wait for incoming connection request connectionSocket = welcomeSocket.accept() create socket, port=x, for incoming request: welcomeSocket = ServerSocket() create socket, connect to hostid, port=x clientSocket =

Socket()

close connectionSocket

read reply from clientSocket close clientSocket hostid

send request using clientSocket read request from

connectionSocket write reply to connectionSocket

Socket

• Socket(InetAddress address, int port)

– Creates a stream socket and connects it to the specified port number at the specified IP address.

• InputStream getInputStream()

– Returns an input stream for this socket. • OutputStream getOutputStream()

– Returns an output stream for this socket. • void close()

– closes this socket (cuts the connection)

ServerSocket

A server socket that can wait for connections from other machines

• public ServerSocket(int port) throws IOException

– Creates a ServerSocket that will receive connection requests on the specified port.

• public Socket accept() throws IOException

– Waits for an incoming connection request, creates the connection, and returns the Socket created on this end. • public void close() throws IOException

(5)

ServerSockets

• A ServerSocket binds to a particular local port.

• Then it calls accept()to listen for incoming connections; accept()blocks until a connection is detected.

• When accept()unblocks this means that a client has connected. It returns a Socketobject which is used to communicate with the remote client. • There are no getInputStream() or getOutputStream() methods for

ServerSocket.

ServerSocket(1234)

Socket(“128.250.25.158”, 1234)

Output/write stream

Input/read stream

Client Server

Exemplo: ServerSocket

1. class ServerExample {

2. public static void main(String[] args) { 3. try {

4. ServerSocket ssock = new ServerSocket(3333);

5. Socket sock = ssock.accept(); 6. BufferedReader br = new BufferedReader( 7. new InputStreamReader(sock.getInputStream())); 8. System.out.println(br.readLine());

9. sock.close();

10. } catch(Exception e) { ... } 11.} }

Exemplo: client Socket

class ClientExample {

public static void main(String[] args) { try {

Socket sock = new Socket( “server.dei.uc.pt”, 3333);

PrintWriter out = new PrintWriter(

sock.getOutputStream(), true);

out.println(“Hello”); sock.close();

} catch(Exception e) { ... } } }

(6)

BufferedReader

methods

void

close

() Close the stream.

int

read

()

Read a single character.

int

read

(char[] cbuf, int off, int len)

Read characters into a portion of an array.

String readLine()

Read a line of text.

DataInputStream

methods

int read(byte[] b) reads some number of bytes into the buffer array b. int read(byte[] b, int off, int len) reads up to len bytes into an array of bytes. char readChar() reads a char.

double readDouble() reads a double value. int readInt() reads a int value.

void readFully(byte[] b) reads some bytes and stores them into the buffer array. String readLine()

Deprecated.This method does not properly convert bytes to characters. The preferred way to read lines of text is via the BufferedReader.readLine() method. Programs that use the DataInputStream class to read lines can be converted to use the BufferedReader class by replacing code of the form: DataInputStream d = new DataInputStream(in); with: BufferedReader d = new BufferedReader(new InputStreamReader(in));

String readUTF() reads a string (encoded in UTF-8 format).

DataOutputStream

methods

void

flush

() flushes this data output stream.

void

write

(int b) writes the specified byte.

void

writeDouble

(double v) writes a double.

void

writeInt

(int v) writes an int.

void

writeUTF

(String

str) Writes a string.

PrintWriter

methods

void

close

()

Close the stream.

void

flush

()

Flush the stream.

void

print

(char c)

Print a character.

void

print

(char[] s)

Print an array of chars.

void

print

(double d)

Print a double .

void

print

(int i)

Print an integer.

void

print

(Object

obj)

Print an object.

void

print

(String

s)

Print a string.

(7)

Exceptions

• exceptions

: Almost all methods in

networking classes throw

IOExceptions

that must be caught because of potential

network problems.

Exceptions

try {

Socket client = new Socket(host, port);

handleConnection(client);

}

catch(

UnknownHostException

uhe) {

System.out.println("Unknown host: " + host);

uhe.printStackTrace();

}

catch(

IOException

ioe) {

System.out.println("IOException: " + ioe);

ioe.printStackTrace();

}

Outro Exemplo: Sockets TCP

Cliente

// 1. Create a Socket Object:

client = new Socket( server, port_id );

// 2. Create I/O streams for communicating with the server. is = new DataInputStream(client.getInputStream() ); os = new DataOutputStream( client.getOutputStream() ); // 3. Perform I/O or communication with the server: // Receive data from the server:

String line = is.readLine(); // Send data to the server:

os.writeBytes("Hello\n"); // 4. Close the socket when done:

(8)

Server

// 1- Open the Server Socket:

ServerSocket server; DataOutputStream os; DataInputStream is;

server = new ServerSocket( PORT ); // 2- Wait for the Client Request:

Socket client = server.accept();

// 3- Create I/O streams for communicating to the client is = new DataInputStream( client.getInputStream() ); os = new DataOutputStream( client.getOutputStream() ); // 4- Perform communication with client

// Receive from client: String line = is.readLine(); // Send to client:

os.writeBytes("Hello\n"); // 5- Close sockets:

client.close(); For multithreaded server:

while(true) {

i. wait for client requests (step 2 above)

ii. create a thread with “client” socket as parameter (the thread creates streams (as in step (3) and does communication as stated in (4). Remove thread once service is provided.

}

Simple Server

import java.io.*; public class SimpleServer{

public static void main(String args[]) throws IOException { // Register service on port 1234

ServerSocket s = new ServerSocket(1234); while(true){

Socket s1=s.accept(); // Wait and accept a connection // Get a stream associated with the socket

OutputStream s1out = s1.getOutputStream(); DataOutputStream dos = new DataOutputStream (s1out); // Send a string!

dos.writeUTF("Ola Boa Noite");

System.out.println("Respondeu ao cliente"); // Close the connection, but not the server socket dos.close(); s1out.close(); s1.close(); } } }

Try this example...

Simple Client

// SimpleClient.java: a simple client program import java.net.*;

import java.io.*; public class SimpleClient {

public static void main(String args[]) throws IOException { // Open your connection to a server, at port 1234 Socket s1 = new Socket(“localhost",1234);

// Get an input file handle from the socket and read the input

InputStreams1In= s1.getInputStream(); DataInputStreamdis= new DataInputStream(s1In); String st = new String (dis.readUTF()); System.out.println(st);

// When done, just close the connection and exit dis.close();

Run SimpleServer, SimpleClient

• Run Server on localhost:

– java SimpleServer • Run Client:

– java SimpleClientOla, Boa Noite

• If you run client when server is not up:

– sockets [1:147] java SimpleClient

– Exception in thread "main" java.net.ConnectException: Connection refused – at java.net.PlainSocketImpl.socketConnect(Native Method) – at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:320) – at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:133) – at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:120) – at java.net.Socket.<init>(Socket.java:273) – at java.net.Socket.<init>(Socket.java:100) – at SimpleClient.main(SimpleClient.java:6)

(9)

Binding

• When a ServerSocket object is created, it attempts to bind to the port on the local host given by the port argument.

– If another server socket is already listening to the port, there will be ajava.net.BindException.

• No more than one process or thread can listen to a particular port at a time.

• For example, if there's already an HTTP server running on port 80, you won't be able to bind to port 80.

Multiple Clients

• Multiple clients can connect to the same port on

the server at the same time.

• The server creates a separate socket for each

client.

Multi-Threaded Servers

• If a server needs to handle many

connections at once, server programs

should be multi-threaded.

Multithreaded Server

Server Threads Server Process Client 1 Process Client 2 Process TCP/IP

(10)

Multi-threaded Server

• One

ServerSocket

can accept multiple clients

simultaneously

• Use multithreading to handle them

• One thread waits for “accept()”

• Open a new thread for each connection.

• Rather than handling the connection directly the socket

should be passed to a

Thread

object that handles the

connection.

Multi-threaded Server (I)

ServerSocket server = new ServerSocket(PORT);

// Server main loop while (true) {

try {

Socket clientSocket = server.accept();

ClientThread theClient = new ClientThread(clientSocket); theClient.start();

}

catch (Exception e) {

// Error accepting one of the clients e.printStackTrace();

} }

Multi-threaded Server (II)

class ClientThread extends Thread

{

private Socket clientSocket;

public ClientThread(Socket clientSocket) { this.clientSocket = clientSocket; }

public void run(){

// Handle the client request here!

}

Threading a Server

• Threads handles the communication between one client and the

server, by spawning a new thread every time a new client connects. • This is often accomplished in C/C++ on a Unix OS by using fork.

– Nowadays the use of Pthreads is also common. • In Java it is simpler thanks to the use ofJava Threads.

(11)

TDayTimeServer.java

import java.net.*; import java.io.*; import java.util.*; public class TDayTimeServer {

public static void main(String argv[]) { try {

ServerSocket listen = new ServerSocket(0);

System.out.println("Listening on:"+listen.getLocalPort()); for(;;) {

Socket client = listen.accept(); System.out.println(clnt.toString());

Connection c = new Connection(client);

} }

catch(Exception e) { System.out.println("Server terminated"); }

}}

Connection.java

import java.net.*; import java.io.*; import java.util.*; class Connection extends Thread {

protected Socket clnt; public Connection(Socket sock) {

clnt = sock; this.start(); }

public void run() { Date today = new Date(); try {

PrintWriter out = new PrintWriter(clnt.getOutputStream(), true); out.println(today); client.close(); } catch (IOException e) {} }}

Exemplos_Sockets.zip

-TCPClient.java

-TCPServer1.java

-TCPServer2.java (multithreaded server)

(12)

UDP - Java Classes

DatagramPacket

– represents a datagram packet

DatagramSocket

– represents a socket for sending and receiving

datagram packets

MulticastSocket

– for sending and receiving IP multicast packets

DatagramSocket

// Constructors

• DatagramSocket()

– Constructs a datagram socket and binds it to any available port on the local host machine.

• DatagramSocket(int port)

– Constructs a datagram socket and binds it to the specified port on the local host machine.

• DatagramSocket(int port, InetAddress iaddr)

• • // Methods • void close() • InetAddress getLocalAddress() • int getLocalPort() • int getSoTimeout() • void receive(DatagramPacket p) • void send(DatagramPacket p) • setSoTimeout(int timeout)

Client/server socket interaction: UDP

hostid

read reply from C_Socket create socket, C_Socket = DatagramSocket()

Create, address (hostid, port=x, send datagram request using C_Socket create socket, port=x, for incoming request: S_Socket = DatagramSocket()

read request from S_Socket write reply to S_Socket specifying client host address, port number

DatagramPacket

//Constructors

public DatagramPacket(byte[] buf, int length)

Constructs a DatagramPacket for receiving.

publicDatagramPacket(byte[] buf, int length, InetAddress address, int port)

Constructs a datagram for sending to the specified port number on the specified host.

// Methods

public synchronized InetAddress getAddress(); public synchronized int getPort();

public synchornized byte[] getData(); int getLength();

void setAddress(InetAddress iaddr); void setPort(int iport);

(13)

DatagramPacket

• Datagram packet data is stored as a byte array:

byte[].

• To send a String message via a datagram

we need to

convert it to byte[].

• The String class provides this via the

getBytes()

method.

String msg = “Olá”;

byte[] buf = msg.getBytes();

Sending UDP Datagrams

• To send data to a particular server

– Convert the data into byte array.

– Pass this byte array, its length, the

InetAddress

and the destination port to the

DatagramPacket()

constructor.

– Next create a

DatagramSocket

and send the packet

by using the

send()

method.

Sending a DatagramPacket

try {

InetAddress addr = InetAddress.getByName(“eden.dei.uc.pt"); int port = 9000;

String msg = “Olá Boa Noite"; byte[] msgBytes = msg.getBytes(); DatagramPacket packet

= new DatagramPacket(msgBytes, msgBytes.length, addr, port); DatagramSocket sender = new DatagramSocket();

sender.send(packet); } catch (Exception e) { System.err.println(e); }

DatagramSocket

public void send(DatagramPacket p)

throws IOException

– Sends a datagram packet from this socket.

– The DatagramPacket includes information indicating the data to be sent, its length, the IP address of the remote host, and the port number on the remote host.

(14)

DatagramSocket

public void receive(DatagramPacket p)

throws IOException

– Receives a datagram packet from this socket.

– When this method returns, the DatagramPacket's buffer is filled with the data received. The datagram packet also contains the sender's IP address, and the port number on the sender's machine.

– It blocks until a datagram packet is received.

– If the message is longer than byte[] the message will be truncated

UDP + TCP Ports

• There are separated ports for UDP and TCP.

• Each computer has 65,536 UDP ports as well as its

65,536 TCP ports.

• A server socket can be bound to TCP port 20 at the

same time as a datagram socket is bound to UDP port

20.

DatagramSocket

(client)

DatagramSocket socket = new DatagramSocket(); // send request

InetAddress address = InetAddress.getByName(“eden.dei.uc.pt”); String s = “get_current_time_date”;

byte [] b = s.getBytes();

DatagramPacket packet = new DatagramPacket(b, b.length, address, 4445); socket.send(packet);

// get response byte[] buf = new byte[256];

packet = new DatagramPacket(buf, buf.length); socket.receive(packet);

// display response

String received = new String(packet.getData()); System.out.println(“the time:” + received);

DatagramSocket

(server)

DatagramSocket socket = new DatagramSocket(); // receives a packet request

byte[] buf = new byte[256];

DatagramPacket packetRequest = new DatagramPacket(buf, buf.length); socket.receive(packetRequest);

// Display the request

byte[] data = packetRequest.getData(); String s = new String(data, 0, data.getLength());

System.out.println("Port " + packet1.getPort() + " on " + packet1.getAddress() + " sent this message:“ + s);

if (s.equals(“get_current_time_date”)) {

String theDate = (new Date()).toString(); byte[] bufSend = theDate.getBytes();

(15)

Datagrams Received...

• Use

getPort()

and

getAddress()

to tell where the

packet come from,

getData()

to retrieve the data, and

getLength()

to see how many bytes were in the data.

• If the received packet was too long for the buffer, it's

truncated to the length of the buffer.

• Length is reset when packet is received.

Exemplos_Sockets.zip

-UDPClient.java

-UDPServer.java

Uso de Recursos: TCP vs UDP

C C C C C C TCP SERVER ServerSocket Socket Socket Socket Socket Socket Socket N clientes simultâneos N sockets no Servidor

C C C C UDP SERVER Socket

Leitura de Mensagens Grandes

em Sockets Stream

• int size,tam=0;

while(tam < N){

size=in.readBytes(...);

tam = tam + size;

}

(16)

Object Serialization

Objectos

• Programamos objectos complexos.

• Queremos guardar o estado dos objectos

em disco..

• Queremos enviar objectos para outros

processos através de um socket...

Object Serialization

Object Serialization

Suppose that you have an object and want

to send it across a socket…

(…)

Pessoa p = new Pessoa(“Bush”, 50);

// enviar o objecto p através de um socket

(…)

public class Pessoa{ private String name; private int age;

public Pessoa(String name, int age) { this.name = name;

Object Serialization

• It is possible to send complete objects through a socket stream

ObjectInputStream .readObject()

ObjectOutputStream .writeObject()

• When reading an object from a ObjectInputStream, it is necessary to cast it to the appropriate type

– Pessoa p = (Pessoa) in.readObject(); • For being able to send object through a stream, they must be

serializable(i.e. they must implementjava.io.Serializable) – Although many classes are serializable, some are not – Ex: a Thread is not serializable

(17)

Guardar Objectos em Disco

public class MyClassA implements Serializable { ... } // in some other code elsewhere...

MyClassA tmp=new MyClassA(arg);

FileOutputStream fos=new FileOutputStream(“some.obj”); ObjectOutputStream out=new ObjectOutputStream(fos); out.writeObject(tmp);

out.flush(); out.close();

1. Mark your class serializable

public class Pessoa implements java.io.Serializable {

private String name; private int age;

public Pessoa(String name, int age) { this.name = name;

this.age = age; }

public String toString() {

return "[" + name + "/" + age + "]"; }

}

2. Use the ObjectStreams

• Reading…

ObjectInputStream in = new

ObjectInputStream(clientSocket.getInputStream());

Pessoa x = (Pessoa) in.readObject(); System.out.println(x);

• Writing…

ObjectOutputStream out = new

ObjectOutputStream(socket.getOutputStream()); Pessoa p = new Pessoa(“Busha”, 50);

out.writeObject(p);

Examplo Serialização Objectos

class Dataimplements Serializable{

private int i; private int tabela[]; public Data(int x){

i = x;

tabela = new int[10]; for(int j=0;j<10;j++)

tabela[j]=x; }

public String toString() { return Integer.toString(i); }

public void print_conteudo() { for(int j=0;j<10;j++)

System.out.print(tabela[j]+" " ); System.out.println();

(18)

Client: TCPClient_O

public class TCPClient_O {

public static void main (String args[]) { String texto;

Socket s = null; int serversocket = 6000;

try{ // 1o passo

s = new Socket(host, serversocket); //…

// 2o passo

DataInputStream in = new DataInputStream( s.getInputStream()); DataOutputStream out = new DataOutputStream( s.getOutputStream()); // Criar ObjecOutputStream e ObjectInputStream

ObjectOutputStream obj_o = new ObjectOutputStream(out); ObjectInputStream obj_i = new ObjectInputStream(in);

int contador=0; // 3o passo while(contador < 5){

contador++; Data d = new Data(contador);

obj_o.writeObject(d);

obj_o.flush();

d.print_conteudo();

System.out.println("ENVIEI OBJECTO"); String data = in.readUTF(); System.out.println("Received: "+ data); }

//... catches....

Server: TCPServer1_O

public class TCPServer1_O{

public static void main(String args[]) throws IOException,ClassNotFoundException{ int serverPort = 6000;

//…

listenSocket = new ServerSocket(serverPort); while(true){

System.out.println("A espera de ligacao no socket "+serverPort); try{

clientSocket = listenSocket.accept();

in = new DataInputStream(clientSocket.getInputStream()); out = new DataOutputStream(clientSocket.getOutputStream()); // Criar ObjectinputStream e ObjectOutputStream

ObjectOutputStream obj_o = new ObjectOutputStream(out); ObjectInputStream obj_i = new ObjectInputStream(in);

Data d; while(true){ d = (Data)obj_i.readObject(); System.out.println("Recebeu: "+d); d.print_conteudo(); out.writeUTF("OBJECTO OK"); out.flush(); }// while //... catches….

Exemplos_Sockets.zip

-TCPClient_O.java

-TCPServer1_O.java

Overwriting

writeObject/readObject

public class DemoClass implements Serializable { private int _dat=3;

private static int _sdat=2;

private void writeObject(ObjectOutputStream o) throws IOException {

o.writeInt(_dat); o.writeInt(_sdat); }

private void readObject(ObjectInputStream i) throws IOException, ClassNotFoundException { _dat=i.readInt();

(19)

Objecto com partes não-serializáveis

• What happens if class Foo has a field of type Bar, but

Bar isn’t serializable?

• You get a

NotSerializableException

• Answer: use

read

/

writeObject

to explicitly serialize

parts that can’t be handled otherwise

Foo tmp=new Foo();

ObjectOutputStream out=new ObjectOutputStream; out.writeObject(tmp);

References

Related documents

(40 mg/mL) to overnight culture of Gram-negative bacteria (Pseudomonas aeruginosa and Escherichia coli) and Gram- positive bacteria (Enterococcus faecalis and Staphylococcus..

public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException5. public Socket(InetAddress address, int port, InetAddress localAddress, int

This review argues that while there are divergent results for recall rate studies, reaction time studies and emotional Stroop task studies showed predominant negativity bias in

Tai means belt, and this channel follows a course th a t encircles the waist, binding up the Yin and Yang channels.... It finally moves across the chin and cheekbone and

No, I.m not being paid by this website for advertising it, but it is just a fast and easy way to create the two pages you need in order to sell the Paypal Booster to other

The wellbore characteristics affecting completion con- figuration or component selection are best summarized by reviewing the drilling, evaluation and pre-completion activities

Topic: Berkley Sockets, Silly Window Syndrome, Sliding Window Protocol, Finite State Machine Model.. Sockets are a service provided by

GU Ventures menar också på att selektering genom andra investerare inte utgör starka motiv till varför bolaget genomför syndikatinvetseringar, då deras underlag och restriktioner