Alma Mater Studiorum - Universita' di Bologna
Sede di Cesena
Reti di Calcolatori
L'interfaccia socket in Java
Vedi:
• Sun, Java Networking – Tutorial.
• B. Eckel, Thinking in Java, 2nd Ed., pagg. 904-923.
Copyright © 2006-2014 by Claudio Salati.
Lez. 4
1
Socket Java e socket C
• L’API socket in Java, a differenza di quella in C, non e’
coerentemente multiprotocollo, ma e’ largamente orientata a gestire
comunicazioni solo nel dominio internet.
 Esiste in teoria una classe generica SocketAddress, ma c’e’
poi solo la classe derivata InetSocketAddress.
 Nei costruttori degli oggetti socket si fa normalmente
riferimento direttamente a indirizzi del dominio internet.
 Nell’interfaccia di alcuni metodi delle classi socket compaiono
direttamente indirizzi internet.
 L’API Android per comunicare su Bluetooth e’ basata su un
insieme di classi/socket ad hoc.
• Mentre i socket C si presentano direttamente come una estensione
del sistema operativo (un socket, come un file, e’ accessibile
tramite file descriptor), i socket in Java sono legati allo specifico
ambiente di programmazione: i socket sono classi/oggetti.
 N.B.: in effetti l’accesso ai file in C e’ possibile sia tramite l’API
di sistema Unix (file descriptor) sia tramite l’API della libreria 2
standard C (ADT FILE).
Socket Java e socket C
• Mentre in C i socket sono tutti, a livello di linguaggio, di un unico
tipo, in Java esistono diverse classi di socket,
•
a seconda del protocollo che interfacciano (TCP vs. UDP) e
•
a seconda del ruolo che assumono nella comunicazione
(initiator vs. responder nel setup della connessione).
• Alla fine pero’ le operazioni di trasmissione/ricezione dati sono
ricondotte (almeno per i socket TCP, ma anche per i socket
Bluetooth-Android) alle normali modalita’ Java di lettura e scrittura
su file.
 Cosi’ come nel mondo C ci si e’ ricondotti all’utilizzo delle due
system call read() e write(), definite per operare su file
descriptor relativi a qualunque tipo di risorsa reale.
• In realta’ nel costruttore socket() del C uno degli argomenti in
ingresso e’ il tipo del servizio di comunicazione offerto dal socket,
ma tutti i tipi di socket sono comunque rappresentati da un unico
3
ADT.
Indirizzi Internet: classe InetAddress
.1
This class represents an Internet Protocol (IP) address.
• byte[] getAddress()
• Returns the raw IP address of this InetAddress object.
The result is in network byte order.
• String getHostAddress()
• Returns the IP address of this InetAddress object string in
textual presentation (decimal dotted notation, e.g.
“172.16.11.180”).
• String getHostName()
• Gets the host name for this IP address (of this InetAddress
object).
• If this InetAddress was created with a host name, this host
name will be remembered and returned.
• Otherwise, a reverse name lookup will be performed and the
result will be returned based on the system configured name
lookup service.
4
Indirizzi Internet: classe InetAddress
.2
• static InetAddress getByAddress(String host,
byte[] addr)
• Creates an InetAddress based on the provided host name and IP
address.
• No name service is checked for the validity of the address.
• The host name can either be a machine name, such as "java.sun.com",
or a textual representation of its IP address (decimal dotted notation).
• static InetAddress getByName(String host)
• Creates an InetAddress based on the provided host name and
determines the IP address of the host.
• The host name can either be a machine name, such as "java.sun.com",
or a textual representation of its IP address.
• If a literal IP address is supplied, only the validity of the address format
is checked.
• static InetAddress getByAddress(byte[] addr)
• Returns an InetAddress object given the raw IP address .
• The argument is in network byte order.
• This method doesn't block, i.e. no reverse name service lookup is
performed.
5
Indirizzi Internet: classe InetAddress
.3
• Un InetAddress contiene due informazioni distinte:
1. Il nome della macchina, che puo’ pero’ essere assente.
2. L’indirizzo IP della macchina, che invece deve ovviamente essere presente
perche’ l’InetAddress sia effettivamente utile.
• Quando l’InetAddress e’ creato a partire dal solo nome della macchina
(costruttore getByName()) e’ il costruttore stesso che si preoccupa di
recuperare l’indirizzo IP (tramite name service lookup: cio’ significa che il
metodo getByName() e’ bloccante).
• Se chiedo il nome della macchina che ha un certo InetAddress e questo era
stato costruito a partire solo dall’indirizzo IP, il metodo getHostName(),
effettuando un reverse name lookup, riesce a procurarselo.
• Notare che il costruttore che ha in ingresso sia il nome della macchina che il
suo indirizzo IP non verifica la validita’ (la congruenza) delle due informazioni.
•
Come potrebbe farlo? Dalla descrizione del costruttore, interrogando un
name service (in terminologia DNS, invocando un resolver).
 E’ evidente che parte dell’ambiente di programmazione di rete e’ un name
service che e’ capace di effettuare (avanti e indietro) la traduzione
nome di una macchina  (relativo) indirizzo IP
 E’ evidente che l’accesso al name service e’ costoso, perche’ il suo
utilizzo e’ considerato bloccante per chi lo invoca.
6
Indirizzi Internet: classe InetSocketAddress
•
.1
This class implements an IP Socket Address
IP address + port number
•
It can also be a pair (hostname + port number), in which case an attempt will be
made to resolve the hostname.
•
If resolution fails then the address is said to be unresolved.
•
It provides an immutable object used by sockets for binding, connecting, or as
returned values.
•
The wildcard is a special local IP address.
•
•
It usually means "any" and can only be used for bind operations.
•
Equivale alla costante INADDR_ANY dell'API socket C.
N.B.: questa classe deriva dalla classe astratta SocketAddress, che
“represents a Socket Address with no protocol attachment. As an abstract
class, it is meant to be subclassed with a specific, protocol dependent,
implementation”.
 Ma in realta’ l’unica sottoclasse esistente e’ InetSocketAddress, e nei
metodi delle classi socket compaiono direttamente indirizzi internet. 7
Indirizzi Internet: classe InetSocketAddress
.2
• InetSocketAddress(int port)
• Creates a socket address where the IP address is the wildcard
address and the port number a specified value.
• A valid port value is between 0 and 65535.
• A port number of 0 will let the system pick up an ephemeral port
in a bind operation.
• InetSocketAddress(InetAddress addr, int port)
• Creates a socket address from an IP address and a port
number. A valid port value is between 0 and 65535.
• A port number of 0 will let the system pick up an ephemeral port
in a bind operation.
• A null IP address will assign the wildcard address.
• InetSocketAddress(String hostname, int port)
• Creates a socket address from a hostname and a port number.
• An attempt will be made to resolve the hostname into an
InetAddress.
8
• If that attempt fails, the address will be flagged as unresolved.
Indirizzi Internet: classe InetSocketAddress
.3
• final int getPort()
• Gets the port number.
• final InetAddress getAddress()
• Gets the InetAddress.
• final String getHostName()
• Gets the hostname.
9
Tipi diversi di socket in un contesto CO
Socket server di
associazione (sa)
Socket server di
comunicazione (sc1)
Socket server di
comunicazione (sc2)
Porta server
Porta client 0
Socket client (sc-ac-0)
Connessione 1
Connessione 2
Porta client 1
Porta client 2
Socket client (sc-ac-1)
Socket client (sc-ac-2)
10
Socket
• Sono definite diverse classi per realizzare i diversi ruoli in cui un
socket puo' essere utilizzato
 Infatti a ruoli diversi corrispondono diversi insiemi di operazioni
applicabili
• Socket per la comunicazione connectionless:
• classe DatagramSocket
• Socket per la comunicazione connection-oriented
• classe Socket rappresenta
• un socket client (connesso o non connesso)
• un socket server di comunicazione (connesso)
• classe ServerSocket rappresenta
• un socket server di associazione (connessione)
11
Classe DatagramSocket
• This class represents a socket for sending and receiving
datagram packets.
•
Rappresenta il meccanismo di accesso ad una porta UDP
• A datagram socket is the sending or receiving point for a packet
delivery service (servizio di comunicazione a messaggi).
• E' definita anche la classe DatagramPacket che
rappresenta un datagram UDP.
 In Java la classe DatagramPacket non rappresenta solo il
4SDU, cioe’ il messaggio che il cliente del Servizio di
Trasporto UDP vuole inviare o ha ricevuto dal proprio pari.
 Un DatagramPacket contiene anche informazioni
aggiuntive.
12
Classe DatagramSocket
Costruttori:
• DatagramSocket()
Constructs a datagram socket and binds it to any available port on
the local host machine (indirizzo IP wildcard).
 Quindi il socket e’ bind-ato all’InetSocketAddress
InetSocketAddress(0).
• DatagramSocket(int port)
Constructs a datagram socket and binds it to the specified port on the
local host machine (indirizzo IP wildcard).
• DatagramSocket(int port, InetAddress laddr)
Creates a datagram socket, bound to the specified local address.
• DatagramSocket(SocketAddress bindaddr)
Creates a datagram socket, bound to the specified local socket
address.
If the address bindaddr is null, creates an unbound socket.
13
Classe DatagramSocket
Metodi:
• void bind(SocketAddress addr)
Binds this DatagramSocket to a specific address & port.
• void connect(SocketAddress addr)
Connects this socket to a remote socket address (IP address + port
number).
• void disconnect()
Disconnects the socket.
• SocketAddress getLocalSocketAddress()
Returns the address of the endpoint this socket is bound to, or null
if it is not bound yet.
• SocketAddress getRemoteSocketAddress()
Returns the address of the endpoint this socket is connected to, or
null if it is unconnected.
14
Classe DatagramSocket
Metodi:
• void receive(DatagramPacket p)
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.
This method blocks until a datagram is received. The length field of
the datagram packet object contains the length of the received
message.
If the message is longer than the packet's length, the message is
truncated.
• void send(DatagramPacket p)
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
15
number on the remote host.
Classe DatagramSocket
Metodi:
• void setTrafficClass(int tc)
Sets traffic class (QoS, Quality of Service) or type-of-service (TOS)
octet in the IP datagram header for datagrams sent from this
DatagramSocket.
• void setBroadcast(boolean on)
Enable/disable SO_BROADCAST.
• void close()
Closes this datagram socket.
 Dove e’ l’informazione di destinazione/mittente nei due metodi
send()/receive()? Nel datagram packet!
16
Classe DatagramPacket
Costruttori:
• DatagramPacket(byte[] buf, int length)
Constructs a DatagramPacket for receiving packets of length (fino
a) length.
The length argument must be less than or equal to buf.length.
• DatagramPacket(byte[] buf, int length,
SocketAddress address)
Constructs a datagram packet for sending packets of length length
to the specified port number on the specified host.
• DatagramPacket(byte[] buf, int length,
InetAddress address, int port)
Constructs a datagram packet for sending packets of length length
to the specified port number on the specified host.
17
Classe DatagramPacket
Metodi:
• SocketAddress getSocketAddress()
Gets the SocketAddress (usually IP address + port number) of the
remote host that this packet is being sent to or is coming from.
• void setSocketAddress(SocketAddress address)
Sets the SocketAddress (usually IP address + port number) of the
remote host to which this datagram is being sent.
• byte[] getData()
Returns the data buffer.
• int getLength()
Returns the length of the data to be sent or the length of the data
received.
• void setData(byte[] buf)
Set the data buffer for this packet.
• void setLength(int length)
Set the length for this packet.
18
Classe Socket
• Questa classe rappresenta:
• un socket TCP client, connesso o non connesso.
• un socket TCP server di comunicazione connesso.
• Una istanza di Socket e' associata (in pratica):
• a una connessione TCP in caso di socket connesso.
• ad una porta TCP in caso di socket cliente non connesso.
• Una volta che un socket e' connesso
• gli si possono richiedere l'InputStream e l'OutputStream ad
esso associati:
• InputStream getInputStream()
• OutputStream getOutputStream()
• si puo' leggere dal socket tramite le normali operazioni di lettura
eseguibili sull'InputStream ad esso associato.
• si puo' scrivere sul socket tramite le normali operazioni di scrittura
eseguibili sull'OutputStream ad esso associato.
19
Classe Socket
Costruttori (1):
• Socket()
Creates an unconnected stream socket.
Ma a quale local address e’ bind-ato il socket?
• Socket(InetAddress address, int port)
Creates a stream socket and connects it to the specified port number
at the specified IP address.
Ma a quale local address e’ bind-ato il socket?
• Socket(InetAddress address, int port,
InetAddress localAddr, int localPort)
Creates a stream socket and connects it to the specified remote
address on the specified remote port.
The socket will also bind() to the local address and port supplied.
20
Classe Socket
Costruttori (2):
• Socket(String host, int port)
Creates a stream socket and connects it to the specified port number
on the named host.
Ma a quale local address e’ bind-ato il socket?
• Socket(String host, int port,
InetAddress localAddr, int localPort)
Creates a stream socket and connects it to the specified remote host
on the specified remote port.
The socket will also bind() to the local address and port supplied.
21
Classe Socket
Metodi:
• void bind(SocketAddress bindpoint)
Binds the socket to a local address.
• void connect(SocketAddress endpoint)
Connects this socket to the server.
• SocketAddress getLocalSocketAddress()
Returns the address of the endpoint this socket is bound to, or null
if it is not bound yet.
• SocketAddress getRemoteSocketAddress()
Returns the address of the endpoint this socket is connected to, or
null if it is unconnected.
• void close()
Closes this socket.
22
Classe Socket
Metodi:
• InputStream getInputStream()
Returns an input stream for this socket.
• OutputStream getOutputStream()
Returns an output stream for this socket.
Esempio:
. . .
int serverPort = (new Integer(args[1])).intValue();
Socket socket = new Socket(args[0],
serverPort);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
23
. . .
Classe Socket
Metodi:
• void sendUrgentData(int data)
Send one byte of urgent data on the socket.
The urgent byte is sent after any preceding writes to the socket
OutputStream and before any future writes to the OutputStream.
• void setOOBInline(boolean on)
Enable/disable OOBINLINE (receipt of TCP urgent data).
By default, this option is disabled and TCP urgent data received on a
socket is silently discarded. If the user wishes to receive urgent data,
then this option must be enabled. When enabled, urgent data is
received inline with normal data.
Note, only limited support is provided for handling incoming urgent
data. In particular, no notification of incoming urgent data is provided
and there is no capability to distinguish between normal data and
urgent data unless provided by a higher level protocol.
24
Classe Socket
Metodi:
• void setKeepAlive(boolean on)
Enable/disable SO_KEEPALIVE.
• void setReuseAddress(boolean on)
Enable/disable the SO_REUSEADDR socket option.
• void setTcpNoDelay(boolean on)
Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
• void setTrafficClass(int tc)
Sets traffic class (QoS, Quality of Service) or type-of-service (TOS)
octet in the IP header for packets sent from this socket.
• boolean isConnected()
Returns the connection state of the socket.
25
Classe InputStream
.1.1
• This abstract class is the superclass of all classes representing an
input stream of bytes.
• “Byte”? Cioe’?
• Un “byte” e’ dato di 8 bit in ordine dato: ma solo un dato!
• Quale e’ l’informazione associata?
• In analogia con il linguaggio C, un “byte” corrisponde ad un
oggetto signed char o ad un oggetto unsigned char?
• Che relazione c’e’ tra un “byte” di un InputStream e un byte
Java?
• Applications that need to define a subclass of InputStream must
always provide a method that returns the next byte of input.
• E’ evidentemente l’astrattezza di questo metodo nella classe
InputStream che la rende astratta!
26
Classe InputStream
.1.2
• public void close() throws IOException
• Closes this input stream and releases any system resources
associated with the stream.
• public int available() throws IOException
• Returns an estimate of the number of bytes that can be read from
this input stream without blocking by the next invocation of a
method for this input stream.
• A single read of this many bytes will not block, but may read fewer
bytes.
• The available() method for class InputStream always
returns 0.
 This method should be overridden by subclasses.
• A subclass' implementation of this method may choose to throw an
IOException if this input stream has been closed by invoking
27
the close() method.
Classe InputStream
.2
• Cio’ che rende astratta la classe InputStream e’ che e’ astratto il suo
metodo read().
• E’ quindi questo metodo read() che deve essere definito da ogni
classe concreta derivata da InputStream.
• Questo e’ vero in particolare per la classe dell’oggetto ritornato dal
metodo getInputStream() della classe Socket.
• public abstract int read() throws IOException
• Reads the next byte of data from the input stream.
• The value byte is returned as an int in the range 0 to 255.
 N.B.: quindi l’InputStream e’ visto come una sequenza di byte
senza segno!
• If no byte is available because the end of the stream has been
reached, the value -1 is returned.
• This method blocks until input data is available, the end of the
stream is detected, or an exception is thrown.
28
Classe InputStream
.3.1
public int read(byte[] b) throws IOException
• Reads some number of bytes from the input stream and stores them into
the buffer array (di byte, cioe’ di byte con segno) b.
 N.B.: quindi l’InputStream e’ visto come una sequenza di byte con
segno!
• The number of bytes actually read is returned as an integer.
• This method blocks until
• input data is available,
• end of file is detected, or
• an exception is thrown.
• If b is null, a NullPointerException is thrown.
• If the length of b is zero, then no bytes are read and 0 is returned;
otherwise, there is an attempt to read at least one byte.
29
Classe InputStream
.3.2
public int read(byte[] b) throws IOException
Continua:
• If no byte is available because the stream is at end of file, the value -1 is
returned;
otherwise, at least one byte is read and stored into b. The first byte read
is stored into element b[0], the next one into b[1], and so on.
• The number of bytes read is, at most, equal to the length of b.
• The read(b) method for class InputStream has the same effect as
read(b, 0, b.length).
public int read(byte[] b) throws IOException
{
return (read(b, 0, b.length));
}
30
Classe InputStream
.4.1
public int read(byte[] b, int off, int len)
throws IOException
•
Reads up to len bytes of data from the input stream into an array of
bytes (in realta’, di byte, con segno).
•
An attempt is made to read as many as len bytes, but a smaller
number may be read, possibly zero.
•
The number of bytes actually read is returned as an integer.
•
This method blocks until
• input data is available,
• end of file is detected, or
• an exception is thrown.
•
If b is null, a NullPointerException is thrown.
•
If off is negative, or len is negative, or off+len is greater than
the length of the array b, then an IndexOutOfBoundsException
31
is thrown.
Classe InputStream
.4.2
public int read(byte[] b, int off, int len)
throws IOException
Continua:
•
If len is zero, then no bytes are read and 0 is returned;
otherwise, there is an attempt to read at least one byte.
•
If no byte is available because the stream is at end of file, the value
-1 is returned;
otherwise, at least one byte is read and stored into b.
•
The first byte read is stored into element b[off], the next one into
b[off+1], and so on.
•
The number of bytes read is, at most, equal to len.
•
In every case, elements b[0] through b[off] and elements
b[off+len] through b[b.length-1] are unaffected.
32
Classe InputStream
.4.3
public int read(byte[] b, int off, int len)
throws IOException
Continua:
•
The read(b, off, len) method for class InputStream simply
calls the method read() repeatedly.
•
If the first such call results in an IOException, that exception is
returned from the call to the read(b, off, len) method.
•
If any subsequent call to read() results in a IOException, the
exception is caught and treated as if it were end of file:
• the bytes read up to that point are stored into b and the number
of bytes read before the exception occurred is returned.
 Subclasses are encouraged to (override this method and) provide
a more efficient implementation of this method.
33
Classe InputStream
.5
public int read(byte[] b, int off, int len)
throws IOException
{
if (len==0) return(0);
int bRead; int i;
bRead = read();
if (bRead<0) return(bRead);
// EOF
b[off] = (byte)(bRead < 128 ? bRead : (-256 + bRead));
for (i=1, off+=1; i<len; i+=1, off+=1) {
try {
// N.B. cosa succede se available() non e’ stata ridefinita?
if (available()<=0) return(i);
bRead = read();
b[off] = (byte)(bRead < 128 ? bRead : (-256 + bRead));
} catch (IOException e) {
return(i);
}
}
return(i);
}
34
Byte (senza segno) e byte Java
• byte Java
• Intero con segno nel range -128 .. +127
• Rappresentazione concreta su 1 byte, complemento-a-2
• static byte unsignedByteInInt2byte(int b) {
// 0 <= b <= 255
return ((byte)(b < 128 ? b : (-256+b)));
}
Bit pattern
00000000
00000001
00000010
00000011
. . .
01111110
01111111
10000000
10000001
10000010
10000011
. . .
11111101
11111110
11111111
Intero con segno
-128..127
0
1
2
3
. . .
126
127
-128
-127
-126
-125
. . .
-3
-2
-1
Intero senza segno
0..255
0
1
2
3
. . .
126
127
128
129
130
131
. . .
253
254
255
35
Byte (senza segno), int e byte Java
Ma in realta’ …
Q. Consider the following code snippet:
int x = 241;
byte y = (byte) x;
System.out.println("y is " + y);
I am getting the output as -15. How did the result come as -15?
Please explain.
A. Byte can take only 8 bits with the 8th bit for sign(+ or -).
241 = 11110001
2's complement of 1110001 is 1111 which is 15.
Q: Quindi cosa succede quando converto a byte un valore int?
36
Socket, InputStream e OutputStream
• Il metodo getInputStream() di un socket non ritorna
ovviamente un oggetto di classe InputStream in senso stretto,
ma un oggetto di una classe concreta derivata da InputStream
• La classe concreta dell’oggetto ritornato dal socket
• Definisce ovviamente (necessariamente) il metodo read()
(altrimenti la classe non sarebbe concreta)
• Ridefinisce, per ragioni di efficienza, il metodo
read(byte[] b, int off, int len)
• Ridefinisce, ragionevolmente, il metodo available()
• Discorso analogo vale ovviamente, in modo simmetrico, per la
classe OutputStream e per l’oggetto ritornato dal metodo
getOutputStream() della classe Socket
37
Classe OutputStream
.1
• This abstract class is the superclass of all classes representing an
output stream of bytes (“byte”? Cioe’? Vedi classe InputStream).
• An output stream accepts output bytes and sends them to some sink.
• Applications that need to define a subclass of OutputStream must
always provide at least a method that writes one byte of output.
• public void close() throws IOException
• Closes this output stream and releases any system resources associated
with this stream.
• The general contract of close is that it closes the output stream.
• A closed stream cannot perform output operations and cannot be
reopened.
• public void flush() throws IOException
• Flushes this output stream and forces any buffered output bytes to be
written out.
• The general contract of flush is that calling it is an indication that, if any
bytes previously written have been buffered by the implementation of the
output stream, such bytes should immediately be written to their intended
38
destination.
Classe OutputStream
.2.1
public abstract void write(int b)
throws IOException
•
Writes the specified byte (cioe’? Vedi seguito!) to this output stream.
•
The general contract for write is that one byte is written to the output
stream.
•
The byte to be written is the eight low-order bits of the argument b.
The 24 high-order bits of b are ignored.
 N.B. il write() di valori int come -1 e 255 (o 65535) produce
esattamente lo stesso effetto.
Il byte piu’ leggero del valore int e’ scritto nell’OutputStream,
indipendentemente dal significato complessivo del valore int.
39
Classe OutputStream
.2.2
public void write(byte[] b) throws IOException
•
Writes b.length bytes from the specified byte array to this output
stream.
•
The general contract for write(b) is that it should have exactly the
same effect as the call write(b, 0, b.length).
 N.B.: nota che, a differenza di quanto avviene con la system call
write() del C, questo, come tutti i metodi write() della classe
Java OutputStream, termina solo quando tutti i byte indicati sono
stati scritti sullo stream.
public void write(byte[] b) throws IOException
{
return (write(b, 0, b.length));
}
40
Classe OutputStream
.3
public void write(byte[] b, int off, int len)
throws IOException
•
Writes len bytes from the specified byte array starting at offset off to
this output stream.
•
The general contract for write(b, off, len) is that some of the
bytes in the array b are written to the output stream in order;
element b[off] is the first byte written and b[off+len-1] is the
last byte written by this operation.
•
If off is negative, or len is negative, or off+len is greater than the
length of the array b, then an IndexOutOfBoundsException is
thrown.
•
The write() method of OutputStream calls the write() method
of one argument on each of the bytes to be written out.
 Subclasses are encouraged to override this method and provide
a more efficient implementation.
41
Lettura di (esattamente) nch byte su socket CO
byte [] readNch (InputStream in, int nch) {
byte [] b = new byte[nch];
int n = 0, j = 0;
try {
while (true) {
n = in.read(b, j, 1);
if (n<0) return null;
// EOF -> errore
if (n==0) continue;
// impossibile
j += 1;
if (j== nch) return b;
}
} catch (Exception e) {
System.err.println("readNch exception:" + e);
System.exit(1);
}
return null;
} //readNch, Copyright © by D. Romagnoli
42
Scrittura di (esattamente) nch byte su socket CO
void writeNch(OutputStream out,
byte [] b, int nch) {
try {
out.write(b, 0, nch);
} catch (Exception e) {
System.err.println ("writeNch exception:" + e);
System.exit(1);
}
} //writeNch, Copyright © by D. Romagnoli
43
Classe ServerSocket
• Questa classe rappresenta un socket server, su cui il processo server
attende nuove richieste di connessione:
• Socket accept()
• Listens for a connection to be made to this socket and accepts
it.
• The method blocks until a connection is made.
• A new Socket is created and returned.
• Una istanza di ServerSocket e' associata ad una porta TCP.
(in realta’ a una porta connessa all porta remota 0.0.0.0:0)
• A seguito della creazione della connessione TCP il ServerSocket
crea un Socket e lo associa alla connessione stessa.
 Il ServerSocket di per se' stesso non e' associato alla
connessione che e’ stata creata e rimane disponibile per attendere
nuove richieste di connessione.
44
Classe ServerSocket
Costruttori:
• ServerSocket()
Creates an unbound server socket
• ServerSocket(int port)
Creates a server socket, bound to the specified port.
• ServerSocket(int port, int backlog)
Creates a server socket and binds it to the specified local port number,
with the specified backlog.
• ServerSocket(int port, int backlog,
InetAddress bindAddr)
Creates a server socket with the specified port, listen backlog, and
local IP address to bind to.
•
N.B.: un ServerSocket puo’ essere costruito gia’ in stato listening:
• Non esiste un metodo esplicito listen().
• Ovviamente, perche’ un socket possa essere in
stato listening esso deve essere gia’ bindato!
45
Classe ServerSocket
Metodi:
• void bind(SocketAddress endpoint)
Binds the ServerSocket to a specific address (IP address and port
number).
• void bind(SocketAddress endpoint, int backlog)
Binds the ServerSocket to a specific address (IP address and port
number).
• Socket accept()
Listens for a connection to be made to this socket and accepts it.
• SocketAddress getLocalSocketAddress()
Returns the address of the endpoint this socket is bound to, or null
if it is not bound yet.
• void setReuseAddress(boolean on)
Enable/disable the SO_REUSEADDR socket option.
• void close()
Closes this socket.
46
System call select()
• Come mai in Java non esiste per operare sui socket un metodo
equivalente alla system call select() del C?
 In realta’ una funzionalita’ tipo select() alla fine e’ stata
aggiunta, ma e’ goffa e poco utilizzata.
• In C lo stile di programmazione classico e’
• Sincrono
• Single-thread
(con l’eccezione della gestione dei segnali, che comunque non e’
di uso generalizzato)
• In Java lo stile di programmazione classico e’
• Sincrono
• Multi-thread
• In Java il problema dell’accesso contemporaneo di un processo a piu’
risorse e’ risolto associando una thread diversa ad ogni flusso dati,
cosi’ che ogni thread non debba accedere ad un certo istante a piu’ di
47
una risorsa.
Scarica

Socket