1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
/*
* Ivy League
*
* Streams
*
* Copyright 1990-2000
* Laboratoire de Recherche en Informatique (LRI)
* Centre d'Etudes de la Navigation Aerienne (CENA)
*
* original code by Michel Beaudouin-Lafon,
* modified by Stephane Chatty and Stephane Sire
*
* $Id$
*
*/
#include "Stream.h"
#include <stdlib.h>
#include <sys/socket.h>
#ifdef __osf__
extern "C" {
int listen (int, int);
}
#endif
/*?class IvlStream
Streams implement reliable point to point connections.
IvlStream connections do not keep the message boundaries:
several messages can be read at a time, and a message can be read in several parts.
Establishing a stream connection is not a symmetric operation:
one process (the server) creates a bound socket and listens to it (with function \fun{Listen});
other processes (the clients) create sockets and connect them to the address of the server.
Each such connection is accepted (\fun{SockAccept}) by the server and results in the creation of a new socket.
Communication with each client will then proceed on this channel,
while the server still can accept connections.
Because a server has to listen to pending connections and communicate
with its connected clients, using a channel set is highly recommended:
when a connection is pending, the channel is ready for reading,
and you can accept the connection with \fun{SockAccept} (instead of reading data).
Note that because \typ{IvlStream} derives from \typ{IvlSocket}
and thus from \typ{IvlChannel}, the virtual functions
\fun{HandleRead} and \fun{HandeWrite} can be used.
?*/
/*?
This constructor is similar to that of the class \typ{IvlSocket}.
?*/
IvlStream :: IvlStream (IvlAddress* bound, IvlAddress* connected)
: IvlSocket (bound, connected)
{
}
/*?nodoc?*/
IvlStream :: IvlStream (const IvlStream& s)
: IvlSocket (s)
{
}
/*?nodoc?*/
IvlStream :: ~IvlStream ()
{
}
/*?nodoc?*/
IvlChannel*
IvlStream :: Copy () const
{
return new IvlStream (*this);
}
/*?nodoc?*/
int
IvlStream :: SockType ()
{
return SOCK_STREAM;
}
/*?
This function implements the Unix system call \fun{listen}.
\var{n} is the maximum number of pending connections:
if \var{n} clients are waiting for the server to accept their connection,
the next client will have its connection refused.
You can safely use the default value.
The stream socket is first set up (with \fun{Setup}), and then the system call is performed.
The returned value is that of the system call, unless the set up failed in which case
-1 is returned.
Note that it is useless to listen on a socket if it is not bound to an address.
?*/
int
IvlStream :: Listen (int n)
{
if (! Setup ())
return -1;
return listen (GetFd (), n);
}
|