PageRenderTime 8ms CodeModel.GetById 3ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 1ms

/Sockets/Sockets.tex

https://github.com/KWMalik/PharoByExample-english
LaTeX | 695 lines | 557 code | 102 blank | 36 comment | 0 complexity | 7b26edb62adc25caf86c3d0aea41b82a MD5 | raw file
  1% $Author$
  2% $Date$
  3% $Revision$
  4% 2011-09-11 - Migrated to PharoBox: svn checkout https://XXX@scm.gforge.inria.fr/svn/pharobooks/PharoByExampleTwo-Eng
  5% could change returns by answers 
  6
  7
  8%=================================================================
  9\ifx\wholebook\relax\else
 10% --------------------------------------------
 11% Lulu:
 12	\documentclass[a4paper,10pt,twoside]{book}
 13	\usepackage[
 14		papersize={6in,9in},
 15		hmargin={.75in,.75in},
 16		vmargin={.75in,1in},
 17		ignoreheadfoot
 18	]{geometry}
 19	\input{../common.tex}
 20	\pagestyle{headings}
 21	\setboolean{lulu}{true}
 22% --------------------------------------------
 23% A4:
 24%	\documentclass[a4paper,11pt,twoside]{book}
 25%	\input{../common.tex}
 26%	\usepackage{a4wide}
 27% --------------------------------------------
 28    \graphicspath{{figures/} {../figures/}}
 29	\begin{document}
 30	%\renewcommand{\nnbb}[2]{} % Disable editorial comments
 31	\sloppy
 32\fi
 33%=================================================================
 34%Noury's commands
 35\newcommand{\nouryComment}[1]{}
 36%\newcommand{\nouryComment}[1]{\textcolor{red}{\textbf{\emph{#1}}}}
 37
 38%=================================================================
 39
 40\chapter{Sockets}\label{cha:sockets}
 41\chapterauthor{\authornoury{}}
 42
 43Modern applications are often distributed on multiple devices and collaborate through a network to achieve some task.
 44The basic approach to set up such a collaboration is to use \textit{sockets}.
 45A typical use is in the World Wide Web. Browsers and servers interact through HTTP sockets.
 46
 47The concept of socket was first introduced by researchers from Berkeley University in the 1960s. They defined the first socket API for the C programming language in the context of Unix operating systems. Since then, the concept of socket was spread out to other operating systems. 
 48Its API was ported to most existing programming languages including Smalltalk.
 49
 50In this chapter, we present the API of sockets in the context of Pharo.
 51We first show through some examples how to use sockets for building both clients and servers.
 52Then, we introduce \ct!SocketStream! and how to use it.
 53In practice, one is likely to use \ct!SocketStream! instead of plain sockets.
 54
 55\section{Basic Concepts}
 56\subsection{Socket}
 57A remote communication involves at least two system processes exchanging some data bytes through a network. Each process accesses the network through at least one socket (see Figure~\ref{fig:socketConcept}).
 58A socket can then be defined as a \textit{plug on a communication network}.
 59
 60\begin{figure}[ht]\centering
 61	\includegraphics[width=.75\linewidth]{socketConcept}
 62	\caption{Inter-Process Remote Communication Through Sockets.}
 63	\label{fig:socketConcept}
 64\end{figure}
 65
 66Sockets are used to achieve a bidirectional communication. They allow both sending and receiving data. 
 67Such interaction can be done according to communication protocols which are encapsulated by sockets. On the Internet and other networks such as ethernet LANs\footnote{Local Area Networks.}, two basic protocols widely used are \textit{TCP/IP} and \textit{UDP/IP}.
 68
 69\subsection{TCP/IP vs. UDP/IP}
 70TCP/IP stands for \textit{Transmission Control Protocol / Internet Protocol} (TCP for short).
 71TCP use guarantees a reliable communication (no data loss). It requires that applications involved in the communication get connected before actually communicating. 
 72Once a connection is established interacting parties can send and receive an arbitrary amount of bytes. This is often referred to as a \textit{stream communication}.
 73Data reach the destination in the same order of their sending.
 74
 75UDP/IP stands for \textit{User Datagram Protocol / Internet Protocol} (UDP for short).
 76Datagrams are chunks of data which size cannot exceed 64KB.
 77UDP is an unreliable protocol because of two reasons.
 78First, UDP does not guarantee that  datagrams will actually reach there destination.
 79The second reason why UDP is qualified as unreliable is that the reception order of multiple datagrams from a single sender to some particular receiver may arrive in an arbitrary order.
 80Nevertheless, UDP is faster than TCP since no connection is required before sending data.
 81A typical use of UDP is  ``heart-beating'' as used in server-based social application, where clients need to notify the server their status (\eg Requesting interactions, or Invisible).
 82
 83\nouryComment{In a future version we will present UDP. But, so  far UDP does not work in \pharo.}
 84In the remainder of this chapter we will focus on TCP Sockets.
 85First, we show how to create a client socket, connect it to a server, exchange data and close the connection (section~\ref{sec:clientTcpSocket}).
 86This lifecycle is illustrated using examples showing the use of client sockets to interact with a web server. 
 87Next, section~\ref{sec:serverTcpSocket} presents server sockets.
 88We describe their life-cycle and how to use them to implement a server that can handle multiple concurrent connections.
 89Last, we introduce in section~\ref{sec:socketStream} socket streams.
 90We give an overview of their benefits by describing their use on both client and server side.
 91 
 92\section{TCP Client}
 93\label{sec:clientTcpSocket}
 94We call \textit{TCP client}  an application that initiates a TCP connection to exchange data with another application: the \textit{server}.
 95It is important to mention that the client and the server may be developed in different languages.
 96The life-cycle of such a client in \pharo decomposes into 4 steps:
 97\begin{enumerate}
 98\item Create a TCP socket.
 99\item Connect the socket to some server.
100\item Exchange data with the server through the socket.
101\item Close the socket.
102\end{enumerate}
103
104\subsection{Create a TCP Socket}
105\pharo provides a single socket class.
106At creation, the socket type (TCP or UDP) is provided to the socket plugin of the virtual machine.
107To create a TCP socket, you need to evaluate the following message 
108\begin{code}{}
109Socket newTCP
110\end{code}
111Method \ct!newTCP! hands out the tcp type (which is stored in the class variable \ct!TCPSocketType!) to set up a TCP socket.
112
113\subsection{Connect a TCP Socket to some Server}
114To connect a TCP Socket to a server, you need to have the object representing the IP address of that server. This address is an instance of \ct!SocketAddress!.
115A handy way to create it is to use \ct!NetNameResolver! that  provides IP style network name lookup and translation facilities.
116
117\Scrref{creatingSocketAddress} provides two examples of socket address creation.
118The first one creates an address from a string describing the server name (\ct!'www.esug.org'!), while the second does the creation from a string representing the  IP address of the server (\ct!'127.0.0.1'!).
119Note that to use the \ct!NetNameResolver! you need to have your machine connected to a network with a DNS\footnote{\emph{Domain Name System}: basically a directory that maps device names to their IP address.}.
120The only exception is for retrieving the local host address, i.e. \ct!127.0.0.1! which is the generic address to refer to the machine that runs your software (\pharo here).
121
122\nouryComment{There are dedicated methods for retrieving the localhost address but they are buggy at the time of writing this text.}
123\nouryComment{The NameLookupFailure exception is used ONLY in NetNameResolver class>>addressForName:timeout:. It should be more widely used.}
124
125\begin{script}[creatingSocketAddress]{Creating a Socket Address}
126| esugAddress localAddress |
127esugAddress := NetNameResolver addressForName: 'www.esug.org'.
128localAddress := NetNameResolver addressForName: '127.0.0.1'.
129\end{script}
130
131Now we can connect our TCP socket to the server as shown in \Scrref{connectingTcpSocket}.
132Message \ct!connectTo:port:! attempts to connect the socket to the server which address and port are provided as parameters.
133\nouryComment{SocketAddress can also store the port of the server. 
134But, NetNameResolver does NOT support building socket address WITH port.}
135
136\begin{script}[connectingTcpSocket]{Connecting a TCP Socket to ESUG Server.}
137| clientSocket serverAddress |
138clientSocket := Socket newTCP.
139serverAddress := NetNameResolver addressForName: 'www.esug.org'.
140clientSocket 
141	connectTo: serverAddress port: 80;
142	waitForConnectionFor: 10.
143clientSocket isConnected
144\end{script}
145
146The \ct!connectTo:port:!  message returns immediately after issuing to the system (through a primitive call) the request to connect the socket.
147Message \ct!waitForConnectionFor: 10! suspends the current process until the socket is connected to the server.
148It waits at most \ct!10! seconds as requested by the parameter.
149If the socket is not connected after 10 seconds, the \ct!ConnectionTimedOut! exception is signaled. 
150Otherwise, the execution can proceed by evaluating the expression \ct!clientSocket isConnected! which obviously answers \ct!true!.
151
152
153
154\subsection{Exchange Data with Server}
155\label{sec:exchangeData}
156Once connection is established, the client can send/receive data to/from the server.
157By data we mean a \ct!ByteString!\footnote{One can send a \ct!ByteArray!, but the receiving socket will return a \ct!ByteString! however.}.
158Typically, the client sends some request to the server and then expects receiving some response.
159Web browsers act according to this schema.
160A web browser is a client that issues a request to some web server identified by the URL.
161Such request is often the path to some resource on the server such as a html file or a picture.
162Then, the browser awaits the server response (\eg html code, picture bytes).
163
164\begin{script}[dataExhangeWithTcpSocket]{Exchanging Data with some Server through a TCP Socket.}
165|clientSocket data|
166... ``create and connect the TCP clientSocket''
167clientSocket sendData: 'Hello server'.
168data := clientSocket receiveData.
169... ``Process data''
170\end{script}
171
172\Scrref{dataExhangeWithTcpSocket} shows the protocol to send and receive data through a client socket.
173Here, we send the string \ct-'Hello server!'- to the server using the \ct!sendData:! message.
174Next, we send the \ct!receiveData! to our client socket to make it wait for data reception.
175Then, the contents of variable \ct!data! is processed.
176
177\begin{script}[dataReceptionTimeOut]{Bounding the Maximum Time for Data Reception.}
178|clientSocket data|
179... ``create and connect the TCP clientSocket''
180[data := clientSocket receiveDataTimeout: 5.
181... ``Process data''
182] on: ConnectionTimedOut 
183do: [:timeOutException|
184	Transcript 
185		cr; 
186		show: 'No data receivedBANG';
187		space;
188		show: 'Network connection is too slow or server is down.']
189\end{script}
190
191%Timeout
192Note that by using  \ct!receiveData!, the client waits until the server either sends no more data, or closes the connection.
193This means that the client may wait indefinitely.
194An alternative is to have the client signal a \ct!ConnectionTimedOut! exception if it had waited too much as shown in \scrref{dataReceptionTimeOut}.
195We use message \ct!receiveDataTimeout:! to ask the client socket to wait for 5 seconds.
196If data is received during this period of time, it is processed silently.
197But if no data is received during the 5 seconds, a \ct!ConnectionTimedOut! is signaled.
198So, we log a description of what happened on the \ct!Transcript!.
199
200\subsection{Close a Socket}
201A TCP socket remains alive while devices at both ends are connected.
202Once the interaction is over, either the server or the client can decide to close the socket.
203This can be done by sending the \ct!close! message to the socket.
204The image where this message is evaluated will then send a close request to the other side.
205The socket remains connected until the other side closes it.
206This may last indefinitely when there is a network failure or when the other side is down.
207This is why sockets also answer the \ct!destroy! message, which frees system resources required by the socket.
208
209In practice we use \ct!closeAndDestroy!. It first attempts to close the socket by sending the \ct!close! message.
210Then, if the socket is still connected after a duration of 20 seconds, the socket is destroyed.
211Note that there exist a variant \ct!closeAndDestroy: seconds! which gets as a parameter the duration to wait before destroying the socket.
212
213\begin{script}[script:closeAndDestroy]{Closing a TCP Socket After Connection to a Web Site.}
214| clientSocket serverAddress httpQuery htmlText |
215httpQuery := 'GET / HTTP/1.1', String crlf, 
216	'Host: www.esug.org:80', String crlf, 
217	'Accept: text/html', String crlfcrlf.
218Transcript cr; cr; show: 'Attempt to get a web page...'.
219serverAddress := NetNameResolver addressForName: 'www.esug.org'.
220clientSocket := Socket newTCP.
221[clientSocket 
222	connectTo: serverAddress port: 80;
223	waitForConnectionFor: 10.
224 clientSocket sendData: httpQuery.
225 htmlText  := clientSocket receiveDataTimeout: 5.
226 Transcript cr; show: htmlText.
227] ensure: [clientSocket closeAndDestroy].
228Transcript cr; show: '...Done'
229\end{script}
230
231To summarize all steps described so far, we use the example of getting a web page from a server in \Scrref{script:closeAndDestroy}.
232First, we retrieve the IP address of the \url{www.esug.org} server.
233Then, we create a TCP socket and connect it to the server.
234We use the IP address we get in the previous step and the default port for web servers: 80.
235Next we forge the HTTP\footnote{HyperText Transfer Protocol used for web communications.} query.
236The string corresponding  to our query starts with the \ct!GET! keyword, followed by a slash saying that we are requesting the root file of the server.
237Follows the protocol version \ct!HTTP/1.1!.
238The second line recalls the host name and port.
239The third and last line of the HTTP query refers to format accepted by our client. 
240Since, we intend to display the result of our query on the \ct!Transcript!, we state that our client accepts texts with html format.
241After sending the http query, we wait at most 5 seconds for the html text that we display on the \ct!Transcript!.
242Socket connection, query sending and html reception are inside a block which execution is ensured to end with cleaning up socket related resources, by means of the \ct!closeAndDestroy! message.
243
244\section{TCP Server}
245\label{sec:serverTcpSocket}
246Now, let us build a simple TCP server. A \textit{TCP Server} is an application that awaits TCP connections from TCP clients. Once connection established, both the server and the client can send a receive data in any order. 
247A big difference between the server and the client is that the server uses at least two sockets.
248One socket is used for handling client connections, while the second serves for exchanging data with a particular client.
249
250\subsection{TCP Socket Server Life-cycle}
251The life-cycle of a TCP server in \pharo  has 5 steps:
252\begin{enumerate}
253\item Create a first TCP socket labelled \textit{socket$_1$}.
254\item Wait for connections by making \textit{socket$_1$}  listen on some port.
255\item Accept a client request for connection. As a result, \textit{socket$_1$} will build a second socket labelled \textit{socket$_2$}.
256\item Exchange data with the client through \textit{socket$_2$}. In the meanwhile, \textit{socket$_1$} can continue to wait for connections, and possibly create new sockets to exchange data with other clients. 
257\item Close \textit{socket$_2$}.
258\item Close \textit{socket$_1$} when we decide to kill the server and stop accepting client connections.
259\end{enumerate}
260
261Concurrency is implicit in this life-cycle.
262The server listens for incoming client connection requests through \textit{socket$_1$}, while exchanging data with some clients through \textit{socket$_2$}.
263The server can even simultaneously exchange data with multiple clients through different sockets.
264In the following, we first illustrate the socket serving machinery.
265Then, we give a complete server class and explain the server life-cycle and related concurrency issues.
266
267\subsection{Serving Basic Example}
268We illustrate the serving basics through a simple example of an echo TCP server that accepts a single client request.
269It sends back to clients whatever data it received and quits.
270The code is provided by \Scrref{servingBasicExample}.
271
272\begin{script}[servingBasicExample]{Basic Echo Server.}
273| connectionSocket interactionSocket |
274connectionSocket := Socket newTCP.
275connectionSocket listenOn: 9999 backlogSize: 10.
276interactionSocket := connectionSocket waitForAcceptFor: 60.
277connectionSocket closeAndDestroy.
278receivedData := interactionSocket receiveData.
279Transcript cr; show: receivedData.
280interactionSocket sendData: 'ECHO: ', receivedData.
281interactionSocket closeAndDestroy.
282\end{script}
283
284First, we create the socket that we will use for handling incoming connections.
285We configure it to listen on port 9999.
286The \ct!backlogSize! is set to 10, meaning that we ask the Operating System to allocate a buffer for 10 connection requests. 
287This backlog will not be actually used in this example.
288But, a more realistic server will have to handle multiple connections and then store pending connection requests into the backlog.
289
290Once the connection socket (referenced by variable \ct!connectionSocket!) is set up, it starts listening for client connections.
291The \ct!waitForAcceptFor: 60! message makes the socket wait connection requests for 60 seconds.
292If no client attempts to connect during these 60 seconds, the message answers \ct!nil!.
293Otherwise, we get a new socket \ct!interactionSocket! connected the client's socket.
294At this point, we do not need the connection socket anymore, so we can close it (\ct!connectionSocket closeAndDestroy! message).
295
296Since the interaction socket is already connected to the client, we can use it to exchange data.
297Messages \ct!receiveData! and \ct!sendData:! presented above (see section~\ref{sec:exchangeData}) can be used to achieve this goal.
298In our example, we wait for data from the client, next we display it on the \ct!Transcript!, and last we send it back to the client prefixed with the \ct!'ECHO: '! string.
299Last, we finish the interaction with the client by closing the interaction socket.
300
301\begin{script}[echoClient]{Echo Client.}
302| clientSocket serverAddress echoString |
303serverAddress := NetNameResolver addressForName:'127.0.0.1'.
304clientSocket := Socket newTCP.
305[clientSocket 
306	connectTo: serverAddress port: 9999;
307	waitForConnectionFor: 10.
308 clientSocket sendData: 'Hello PharoBANG'.
309 echoString  := clientSocket receiveDataTimeout: 5.
310 Transcript cr; show: echoString.
311] ensure: [clientSocket closeAndDestroy].
312\end{script}
313
314
315You cannot test this script totally without having the client code running, for example in a different process or a second image. 
316We do use two different images, one that runs the server code and one for the client code. 
317Indeed, since we use the user interaction process, the \pharo UI will be frozen at some points, such as during the \ct!waitForAcceptFor:!.
318\Scrref{echoClient} provides the code to run on the client image.
319Note that you have to run the server code first.
320Otherwise, the client will fail.
321
322%An alternative to running your own Smalltalk client socket is to use an existing one.
323%On Unix machines, the \ct{nc}\footnote{\ct{nc} stands for \ct{netcat}.} utility is very handy for experimenting with sockets.
324%It can play either a client or a server role for both TCP and UDP.
325%To run an \ct{nc}-based client for our server, evaluate the following expression on terminal:
326%\begin{code}{}
327%cat | nc localhost 9999
328%\end{code}
329%
330%The \ct{cat} command allows you to type-in some text.
331%Once you're done, type \ct{ctrl-D}.
332%The pipe connects the output of \ct{cat} to the input of \ct{nc}.
333%Here, we use \ct{nc} as client that sends the text we provided to a server on the local host, listening on port 9999.
334
335\subsection{Echo Server Class}\label{sec:echoServerClass}
336We define here the \ct!EchoServer! class that deals with concurrency issues.
337It handles concurrent client queries and it does not freeze the UI.
338As we can see in the definition labelled \clsref{echoServerClassDef}, the \ct!EchoServer! declares three instance variables.
339The first one (\ct!connectionSocket!) refers to the socket used for listening to client connections.
340The two last instance variables (\ct!isRunning! and \ct!isRunningLock!) are used to manage the server process life-cycle while dealing with synchronization issues.
341 
342\begin{classdef}[echoServerClassDef]{\ct!EchoServer! Class Definition}
343Object subclass: #EchoServer
344	instanceVariableNames: 'connectionSocket isRunning isRunningLock'
345	classVariableNames: ''
346	poolDictionaries: ''
347	category: 'SimpleSocketServer'
348\end{classdef}
349
350\begin{method}[meth:serverInitialize]{The \ct!EchoServer>>>initialize! Method}
351EchoServer>>>initialize 
352	super initialize.
353	isRunningLock := Mutex new.
354	self isRunning: false
355\end{method}
356
357\begin{method}[meth:isRunningRead]{The \ct!EchoServer>>>isRunning! Read Accessor}
358EchoServer>>>isRunning
359	^isRunningLock critical: [isRunning]
360\end{method}
361
362\begin{method}[meth:isRunningWrite]{The \ct!EchoServer>>>isRunning:! Write Accessor}
363EchoServer>>>isRunning: aBoolean
364	isRunningLock critical: [isRunning := aBoolean]
365\end{method}
366
367The \ct! isRunning! instance variable is a flag that is set to \ct!true! while the serving is running.
368As we will see below, it can be accessed by different processes.
369Therefore, we use the mutex (see \mthref{meth:serverInitialize}) referenced using the \ct!isRunningLock! instance variable. 
370This mutex ensures that a single process can read or write the value of \ct!isRunning! (use of the \ct!critical:! message in \mthref{meth:isRunningRead} and \mthref{meth:isRunningWrite}).
371
372\begin{method}[meth:stop]{The \ct!EchoServer>>>stop! Method}
373EchoServer>>>stop
374	self isRunning: false
375\end{method}
376
377In order to manage the life-cycle of our server, we introduced two methods \ct!EchoServer>>>start! and \ct!EchoServer>>>stop!.
378We begin with the simplest one \ct!EchoServer>>>stop! which definition is provided as \mthref{meth:stop}.
379It simply sets the \ct!isRunning! flag to \ct!false!.
380This will have the consequence of stopping the serving loop in method \ct!EchoServer>>>serve! (see \mthref{meth:serve}). 
381
382\begin{method}[meth:serve]{The \ct!EchoServer>>>serve! Method}
383serve
384| interactionSocket |
385[[self isRunning]
386	whileTrue: [self interactOnConnection]]
387	ensure: [connectionSocket closeAndDestroy]
388\end{method}
389
390The activity of the serving process is implemented in the \ct!serve! method (see \mthref{meth:serve}).
391It interacts with clients on connections while the \ct!isRunning! flag is \ct!true!.
392After a \ct!stop!, the serving process is terminates by destroying the connection socket.
393The \ct!ensure:! message guarantees that that this destruction is performed even if the serving process is terminated abnormally. 
394Such termination may occur because of an exception (\eg network disconnection) or a user action (\eg through the process browser).   
395
396\begin{method}[meth:start]{The \ct!EchoServer>>>start! Method}
397start
398	isRunningLock critical: [
399		self isRunning ifTrue: [^self].
400		self isRunning: true].
401	connectionSocket := Socket newTCP.
402	connectionSocket listenOn: 9999 backlogSize: 10.
403	[self serve] fork
404\end{method}
405
406The creation of the serving process is the responsibility of method \ct!EchoServer>>>start! (see the last line of \mthref{meth:start}).
407The \ct!EchoServer>>>start! method first checks if the server is already running.
408It returns if the \ct!isRunning! flag is set to \ct!true!.
409Otherwise, a TCP socket dedicated to connection handling is created and made to listen on port 9999.
410The backlog size is set to 10 that is -as mentioned above- the system allocates a buffer for storing 10 pending client connection requests.
411This value is a trade-off that depends on how fast is the server (varies according to the VM and the hardware) and the maximum rate of client connections requests.
412The backlog size should be big enough to avoid losing any connection request, but not too big to avoid wasting memory.
413Finally \ct!EchoServer>>>start! method creates a process by sending the \ct!fork! message to the \ct![self serve]! block.
414The created process has the same priority as the creator process (i.e. the one that performs the \ct!EchoServer>>>start! method).
415
416
417\begin{method}[meth:interactOnConnection]{The \ct!EchoServer>>>interactOnConnection! Method}
418interactOnConnection
419	| interactionSocket |
420	interactionSocket := connectionSocket waitForAcceptFor: 1 ifTimedOut: [^self].
421	[self interactUsing: interactionSocket] fork
422\end{method}
423
424Method \ct!EchoServer>>>serve! (see \mthref{meth:serve}) loop interacts with clients on connections.
425This interaction is handled in the \ct!EchoServer>>>interactOnConnection! method (see \mthref{meth:interactOnConnection}) .
426First, the connection socket waits for client connections for one second.
427If no client attempts to connect during this period we simply return.
428Otherwise, we get as result another socket dedicated to interaction.
429To process other client connection requests, the interaction is performed in another process, hence the \ct!fork! in the last line.
430
431\begin{method}[meth:interactUsing]{The \ct!EchoServer>>>interactUsing:! Method}
432interactUsing: interactionSocket
433	| receivedData |
434	[receivedData := interactionSocket receiveDataTimeout: 5.
435	 Transcript cr; show: receivedData.
436	 interactionSocket sendData: 'ECHO: ', receivedData]
437		ensure: [interactionSocket closeAndDestroy]
438\end{method}
439The interaction as implemented in method \ct!EchoServer>>>interactUsing:! (see \mthref{meth:interactUsing}) with a client boils down to reading data provided by the client and sending it back prefixed with the \ct!'ECHO: '! string.
440It worth noting that we ensure that the interaction socket is destroyed, whether we have exchanged data or not (timeout).
441
442\section{SocketStream}
443\label{sec:socketStream}
444\ct!SocketStream! is a read-write stream that encapsulates a TCP socket.
445It eases the data exchange by providing buffering together with a set of facility methods.
446
447\subsection{SocketStream at Client Side}
448We illustrate here socket stream use at client side.
449The following code snippet (\Scrref{script:streamGetLine}) shows how the client uses a socket stream to get the first line of a webpage.
450
451\begin{script}[script:streamGetLine]{Getting the first line of a web page using \ct!SocketStream!.}
452	|stream httpQuery result|
453	stream := SocketStream 
454			openConnectionToHostNamed: 'www.pharo-project.org' 
455			port: 80.
456	httpQuery := 'GET / HTTP/1.1', String crlf, 
457		'Host: www.pharo-project.org:80', String crlf, 
458		'Accept: text/html', String crlf.
459	[
460		stream sendCommand: httpQuery.
461		Transcript cr; show: stream nextLine.
462	] ensure: [
463		stream close]
464\end{script}
465
466The first line creates a stream that encapsulates a newly created socket connected to the provided server.
467It is the responsibility of message \ct!openConnectionToHostNamed:port:!.
468It suspends the execution until the connection with the server is established.
469If the server does not respond, the socket stream signals a \ct!ConnectionTimedOut! exception.
470This exception is actually signaled by the underlying socket.
471The default timeout delay is 45 seconds (defined in method \ct!Socket class>>>standardTimeout!).
472One can choose a different value using the \ct!SocketStream>>>timeout:! method.
473
474Once our socket stream connected to the server, we forge and send an HTTP GET query.
475Notice that compared to \scrref{script:closeAndDestroy} we skipped here (\Scrref{script:streamGetLine}) one final \ct!String crlf!.
476This is because the \ct!SocketStream>>>sendCommand:! method automatically inserts CR and LF characters after sent data to mark line ending.
477
478Reception of the requested web page is triggered by sending the \ct!nextLine! message to our socket stream.
479It will waits a few seconds until data is received.
480Data is then displayed on the transcript.
481We safely ensure that the connection is closed.
482
483In this example, we only display the first line of response sent by the server.
484We can easily display the full response including the html code by sending the \ct!upToEnd! message to our socket stream.
485Note however that you will have to wait a bit longer compared to displaying a single line.
486
487\subsection{SocketStream at Server Side}
488SocketStreams may also be used at server side to wrap the interaction socket as shown in \Scrref{script:streamSimpleServer}.
489
490\begin{script}[script:streamSimpleServer]{Simple Server using \ct!SocketStream!.}
491|connectionSocket interactionSocket interactionStream|
492connectionSocket := Socket newTCP. 
493[
494	connectionSocket listenOn: 12345 backlogSize: 10. 
495	interactionSocket := connectionSocket waitForAcceptFor: 30. 
496	interactionStream := SocketStream on: interactionSocket.
497	interactionStream sendCommand: 'Greetings from Pharo Server'.
498	Transcript cr; show: interactionStream nextLine.
499] ensure: [
500	connectionSocket closeAndDestroy.
501	interactionStream ifNotNil: [interactionStream close]
502]
503\end{script}
504
505A server relying on socket streams still uses a socket for handling incoming connection requests.
506Socket streams come into action once a socket is created for interaction with a client.
507The socket is wrapped into a socket stream that eases data exchange using messages such as \ct!sendCommand:! or \ct!nextLine!.
508Once we are done, we close and destroy the socket handling connections and we close the interaction socket stream.
509This latter will take care of closing and destroying the underlying interaction socket.
510
511\subsection{Binary vs. Ascii mode}
512Data exchanged can be treated as bytes or characters depending.
513When a socket stream is configured to exchange bytes by means of message \ct!binary! it organizes sent and received data as byte arrays.
514Conversely, when a socket stream is configured to exchange characters (default setting) by means of message \ct!ascii! it organizes sent and received data as Strings.
515
516Suppose we have an instance of the \ct!EchoServer! (see section~\ref{sec:echoServerClass}) started by means of the following expression
517\begin{code}{}
518server := EchoServer new.
519server start.
520\end{code}
521
522The default behavior of socket stream is to handle ascii strings on sends and receptions.
523We show instead in \Scrref{script:binarySocketStream} the behavior in binary mode.
524The \ct!nextPutAllFlush:! message receives a byte array as argument.
525It puts all the bytes into the buffer then immediately triggers the sending (hence the \ct!Flush! in the selector).
526The \ct!upToEnd! message answers an array with all bytes sent back by the server.
527Note that this message blocks until the connection with the server is closed.
528
529
530\begin{script}[script:binarySocketStream]{A \ct!SocketStream! Interacting in Binary Mode.}
531interactionStream := SocketStream 
532									openConnectionToHostNamed: 'localhost' port: 9999.  
533interactionStream binary.
534interactionStream nextPutAllFlush: #[65 66 67].
535interactionStream upToEnd.
536\end{script}
537
538It is worth noting that whether the client manages strings (ascii mode) or byte arrays (binary mode) has no impact on the server.
539Indeed, in ascii mode, the socket stream handles instances of \ct!ByteString!.
540So, each character maps to a single byte. 
541
542\subsection{Delimiting Data}
543SocketStream acts simply as a gateway to some network. 
544It sends or reads bytes without giving them any semantics.
545The semantics, that is the organization and meaning of exchanged data should be handled by other objects.
546Developers should decide a protocol to use and to enforce on both interacting sides in order to have correct interaction.
547
548A good practice is to \emph{reify} a protocol, that is to materialize it as an object which wraps a socket stream. 
549The protocol object analyzes exchanged data and decides accordingly which messages to send to the socket stream.
550Involved entities in any conversation need a protocol that defines how to organize data into sequence of bytes or characters.
551Senders should conform to this organization to allow receivers extract valid data from received sequence of bytes.
552 
553One possible solution is to have a set of delimiters inserted between bytes or characters corresponding to each data.
554An example of delimiter is the sequence of ASCII characters CR and LF.
555This sequence is considered so useful that the developers of the \ct!SocketStream! class introduced the \ct!sendCommand:! message.
556This method (illustrated in \scrref{script:closeAndDestroy}) does append CR and LF after sent data.
557When reading CR followed by LF the receiver knows that the received sequence of characters is complete and can be safely converted into valid data.
558A facility method \ct!nextLine! (illustrated in \scrref{script:streamGetLine}) is implemented by \ct!SocketStream! to perform reading until the reception of CR+LF sequence.
559One can however use any character or byte as a delimiter.
560Indeed, we can ask a socket stream to read all characters/bytes up to some specific one using the \ct!upTo:! message.
561
562The advantage of using delimiters is that it handles data of arbitrary size.
563The cons is that we need to analyze received bytes or characters to find out the limits, which is resource consuming.
564An alternative approach is to exchanged bytes or characters organized in chunks of a fixed size.
565A typical use of this approach is for streaming audio or video contents.
566
567\begin{script}[script:streamNextPutAllStartingAt]{A content streaming source sending data in chunks.}
568interactionStream := "create an instance of SocketStream". 
569contentFile := FileStream fileNamed: '/Users/noury/Music/mySong.mp3'.
570contentFile binary.
571content := contentFile upToEnd.
572chunkSize := 3000.
573chunkStartIndex := 1.
574[chunkStartIndex < content size] whileTrue: [
575	interactionStream next: chunkSize putAll: content startingAt: chunkStartIndex.
576	chunkStartIndex := chunkStartIndex + chunkSize.
577]
578interactionStream flush.
579\end{script}
580
581\Scrref{script:streamNextPutAllStartingAt} gives an example of a script streaming an mp3 file.
582First we open a binary (mp3) file and retrieve all its content (message \ct!upToEnd:!).
583Then we loop, sending data in chunks of 3000 bytes.
584We rely on the \ct!next:putAll:startingAt:! message that takes three arguments: the size (number of bytes or characters) of the data chunk,
585the data source (a sequenceable collection) and the index of the first element of the chunk.
586In this example, we make the assumption that the size of the content collection is a multiple of the chunk size.
587Of course, in a real setting, this assumption does not hold and one needs to deal with the last part of data that is smaller than a chunk.
588A possible solution is to replace missing bytes with zeros.
589
590\begin{script}[script:socketStreamNext]{Reading data in chunks using \ct!SocketStream!.}
591	|interactionStream chunkSize chunk|
592	interactionStream := SocketStream 
593											openConnectionToHostNamed: 'localhost' port: 9999.
594	interactionStream isDataAvailable ifFalse: [(Delay forMilliseconds: 100) wait].
595	chunkSize := 5.
596	[interactionStream isDataAvailable] whileTrue: [
597		chunk  :=  interactionStream next: chunkSize.
598		Transcript cr; show: chunk
599	].
600	interactionStream close.
601	Transcript cr; show: 'DONE!'
602\end{script}
603
604
605In order to read data in chunks, \ct!SocketStream! does respond to the \ct!next:! message as illustrated by \scrref{script:socketStreamNext}.
606We consider that we have a server running at port 9999 of our machine that sends a string which size is a multiple of 5.
607Right after the connection, we wait 100 milliseconds until the data is received.
608Then, we read data in chunks of 5 characters that we display on the Transcript.
609So, if the server sends a string with 10 characters \ct!'HelloWorld'!, we will get on the Transcript \ct!Hello! on one line and \ct!World! on a second line.
610
611\section{Tips on Networking Experiments}
612In sections related to client-side sockets and socket streams, we use interactions with a web server as an example.
613So, we forge an HTTP Get query and send it to the server.
614It worth noting that we chose these examples to make experiments straightforward and platform agnostic.
615In real scale applications, interactions involving HTTP should be coded using a higher level library such as Zinc HTTP\footnote{\url{http://zn.stfx.eu/zn/index.html}}.
616
617To experiment without dealing with HTTP, we can use Unix utilities.
618Readers with a Unix machine (Linux, Mac OS X) or with Cygwin (for Windows) can use \ct!nc! (or netcat), \ct!netstat! and \ct!lsof! for their tests.
619
620\subsection{\ct!nc! (netcat)}
621\ct!nc! allows to set up either a client or a server for both TCP (default protocol) and UDP.
622It redirects the content of its \ct!stdin! to the other side.
623The following snippet show how to send \ct!'Hello from a client'! to a server on the local machine listening on port 9090.
624\begin{code}{}
625echo Hello from a client | nc 127.0.0.1 9090 
626\end{code}
627
628The command line below starts a server listening on port 9090 that sends \ct!'Hi from server'! to the first client to connect.
629It terminates after the interaction.
630\begin{code}{}
631echo Hi from server | nc -l 9090 
632\end{code}
633
634You can keep the server running by means of option \ct!-k!.
635But, the string produced by the preceding \ct!echo! is sent only to the first client to connect.
636An alternative solution is to make the \ct!nc! server send text you type.
637Simply evaluate the following command line. 
638\begin{code}{}
639echo nc -lk 9090 
640\end{code}
641
642Type in some text in the same terminal where you started the server.
643Then, run a client in another terminal.
644Your text will be displayed on the client side.
645You can repeat these two last actions (type text at the server side, then start client) as many times as needed.
646
647You can even go more interactive by making the connection between a client and a server more persistent.
648By evaluating the following command line, the client sends every line (ended with "Enter").
649It will terminate when sending the EOF signal (ctl-D).
650\begin{code}{}
651echo cat | nc -l 9090 
652\end{code}
653
654
655\subsection{\ct!netstat!}
656This command provides various information on network interfaces and sockets of your computer.
657It provides many statics so one need to use appropriate options to filter out useful information.
658The following command line allows displaying status of tcp sockets and their addresses.
659Note that the port numbers and addresses are separated by a dot.
660\begin{code}{}
661netstat -p tcp -a -n
662\end{code}
663 
664\subsection{\ct!lsof!}
665The \ct!lsof! command lists all files open in your system.
666This of course includes sockets, since everything is a file in Unix.
667Why \ct!lsof! is useful, would you say, if we already have \ct!netstat!?
668The answer is that \ct!lsof! shows the link between processes and sockets.
669So, you can find out sockets related to your program.
670
671The example provided by following command line lists TCP sockets.
672The \ct!n! and \ct!P! options force \ct!lsof! to display host addresses and ports as numbers. 
673\begin{code}{}
674lsof -nP -i tcp
675\end{code}
676
677
678\section{Chapter summary}
679In this chapter we presented how to use TCP sockets and socket streams to develop both clients and servers.
680As mentioned in the introduction, we recommend to use socket streams which are of higher level and provide facility methods.
681They were successfully used in projects such as Swazoo and Kom web servers used respectively by AidaWeb and Seaside web frameworks.
682
683Nevertheless, socket streams remain still low-level if you have an application involving different objects distributed over communicating images.
684In a such software, developers need to deal with message passing between remote objects by serializing arguments and results.
685They will have also to take care of distributed garbage-collection.
686An object should not be destroyed if it is referenced by a remote one.
687This recurrent not trivial issues are solved by Object-Request Brokers (ORB) such as rST\footnote{http://www.squeaksource.com/rST.html}.
688An ORB frees the developer from networking issues and thus allows expressing remote communications simply using messages exchanged between remote objects.
689
690% Noury: Pour pousser le message "Utilisez les SocketStream", est-ce Ben tu pourras remplacer les socket par des SocketStream dans ton code ?
691% Reference to a chat instant messages:  on Squeaksource: http://www.squeaksource.com/PharoInstantMessenge \ben{maybe it should be moved in another repo}. You can load it using Monticello (Chapter \ja{numChapter}).
692
693%=================================================================
694\ifx\wholebook\relax\else\end{document}\fi
695%=================================================================