This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA
id | title | abstract | author | language | filesize | "; 19state | actions|
---|---|---|---|---|---|---|---|
$id | $title | "; 33$abstract | $author | "; 34$language | $filesize | "; 35$state | "; 36 37"; 38 echo "Accept "; 39 echo "Reject "; 40 echo "Modify "; 41 echo "Delete "; 42 echo " | "; 43
"; 50
?> 51
Back to Main Menu 52
53
echo-client.cpp 2
* 3
* Copyright (c) 2000 Sean Walton and Macmillan Publishers.
Use may
be in 4
* whole or in part in accordance to the General Public License
(GPL). 5
* 6
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 7
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE 8
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 9
* ARE DISCLAIMED.
LIABLE
IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
10
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 11
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS 12
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 13
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT 14
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 15
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF 16
* SUCH DAMAGE. 17
*/
18 19
/******************************************************************* **********/ 20
/*** echo-client.cpp ***/ 21
/*** ***/ 22
/*** Demonstrate creating SocketClient object. ***/ 23
/******************************************************************* **********/ 24 25
#include <stdlib.h> 26
#include <stdio.h> 27
#include "socket.h" 28 29
int main(int count, char *strings[]) 30
{
31 32 33
if ( count != 2 ) { printf("usage: %s
34
exit(1);
35 36
}
37 38
HostAddress addr(strings[1]); try
39 40 41 42
{ SocketClient client(addr); TextMessage msg(1024); do
43 44 45 46 47 48 49
{ char line[100]; client.Receive(msg); printf("msg=%s", msg.GetBuffer()); fgets(line, sizeof(line), stdin); msg = line; client.Send(msg);
50
}
51
while ( strcmp(msg.GetBuffer(), "bye\n") != 0 );
52 53 54 55
} catch (Exception& err) { err.PrintException();
56 57 58 59
} catch (...) { fprintf(stderr, "Unknown error\n");
60 61 62
} return 0;
} echo-server.cpp 2
* 3
* Copyright (c) 2000 Sean Walton and Macmillan Publishers.
Use may
be in 4
* whole or in part in accordance to the General Public License
(GPL). 5
* 6
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 7
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE 8
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 9
* ARE DISCLAIMED.
LIABLE
IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
10
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 11
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS 12
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 13
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT 14
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 15
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF 16
* SUCH DAMAGE.
17
*/ 18 19
/******************************************************************* **********/ 20
/*** echo-server.cpp ***/ 21
/*** ***/ 22
/*** Demonstrate creating a SocketServer object. ***/ 23
/******************************************************************* **********/ 24 25
#include <stdlib.h> 26
#include <stdio.h> 27
#include
#include "socket.h" 29 30
TextMessage welcome("Welcome to the EchoServer(TCP)\n"); 31 32
void Echoer(const Socket& client) 33
{
34
try
35 36
{ TextMessage msg(1024);
37
client.Send(welcome);
38
do 39
{
40
client.Receive(msg);
41
printf("bytes=%d: ", msg.GetSize());
42
printf("%s", msg.GetBuffer());
43
client.Send(msg);
44
}
45
while ( msg.GetSize() > 0 "bye\n") != 0 ); 46 47
} catch (Exception& err)
&&
strcmp(msg.GetBuffer(),
48 49
{ err.PrintException();
50 51
}
}
52 53 54
void CreateServer(int port) 55
{
56 57
printf("Listener running...\n");
58
try 59 60
{
61
SocketServer server(port);
62
server.ShareAddress(true);
63 64
server.Accept(Echoer);
65 66 67 68 69
} catch (Exception& err) { err.PrintException();
70 71 72 73
} catch (...) { fprintf(stderr, "Unknown error\n");
74 75
}
76
}
77 78 79
int main(int count, char *strings[]) 80
{
81 82
83
int pid;
84 85 86 87
if ( count != 2 ) { printf("usage: %s <port>\n", strings[0]);
88
exit(1);
89 90
}
91 92 93 94
int port = atoi(strings[1]); if ( port <= 0 ) { printf("Illegal port value: must be >0\n");
95
exit(-1);
96 97
}
98 99 100
CreateServer(port); /*
101
pid = fork(); 102
if (pid != 0 ) { 103
CreateServer(port); 104
} else { 105
CreateServer(port); 106
} 107
*/ 108 109 110
return 0;
} CC=g++ 2
CFLAGS =
-W -D_REENTRANT
3
INCLUDE = 4
LIBDIRS = 5
CLIBS = 6
CALOBS 7
= socket.o
8
peer
: peer.cpp $(CALOBS)
9
$(CC) $(CFLAGS) $(INCLUDE) peer.cpp $(CALOBS) $(LIBDIRS) $(CLIBS) 10
-o peer
11
peer-caller
: peer-caller.cpp $(CALOBS)
12
$(CC) $(CFLAGS) $(INCLUDE) peer-caller.cpp $(CALOBS) $(LIBDIRS) $(CLIBS) -o peer-caller 13 14
peer-replier
: peer-replier.cpp $(CALOBS)
15
$(CC) $(CFLAGS) $(INCLUDE) peer-replier.cpp $(CALOBS) $(LIBDIRS) $(CLIBS) 16
-o peer-replier
17
multicast-peer
: multicast-peer.cpp $(CALOBS)
18
$(CC) $(CFLAGS) $(INCLUDE) multicast-peer.cpp $(CALOBS) $(LIBDIRS) $(CLIBS) -o multicast-peer 19 20
broadcast-peer 21
: broadcast-peer.cpp $(CALOBS)
$(CC) $(CFLAGS) $(INCLUDE) broadcast-peer.cpp $(CALOBS) $(LIBDIRS) 22
$(CLIBS) -o broadcast-peer
23
echo-client 24
: echo-client.cpp $(CALOBS)
$(CC) $(CFLAGS) $(INCLUDE) echo-client.cpp $(CALOBS) $(LIBDIRS) $(CLIBS) -o echo-client 25 26
echo-server 27
: echo-server.cpp $(CALOBS)
$(CC) $(CFLAGS) $(INCLUDE) echo-server.cpp $(CALOBS) $(LIBDIRS) $(CLIBS) 28
-o echo-server
29 30 31
socket.o : socket.cpp socket.h 32 33
$(CC) $(CFLAGS) $(INCLUDE) -c socket.cpp
34
clean: 35
rm *.o socket.cpp 2
*
3
* Copyright (c) 2000 Sean Walton and Macmillan Publishers.
Use may
be in 4
* whole or in part in accordance to the General Public License
(GPL). 5
* 6
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 7
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE 8
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 9
* ARE DISCLAIMED.
LIABLE
IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
10
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 11
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS 12
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 13
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT 14
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 15
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF 16
* SUCH DAMAGE. 17
*/ 18 19
/******************************************************************* **********/ 20
/*** socket.cpp ***/ 21
/*** ***/ 22
/*** Implements the C++ socket framework. ***/ 23
/******************************************************************* **********/ 24 25
#include <stdlib.h> 26
#include <stdio.h> 27
#include
#include
29
#include <string.h> 30
#include <arpa/inet.h> 31
#include
#include
#include
#include <errno.h> 35
#include <signal.h> 36
#include "socket.h" 37 38
//////////////////////////////////////////////////////////////////// /////////// 39
/// SimpleString 40
//---------------------------------------------------------------------------41
//--- Constructors & Destructors 42
SimpleString::SimpleString(const char* s) 43
{
44 45 46 47
Length = strlen(s); Buffer = new char[Length+1]; strcpy(Buffer, s);
}
48 49
SimpleString::SimpleString(const SimpleString& s) 50
{
51 52 53 54
Length = s.GetLength(); Buffer = new char[Length+1]; strcpy(Buffer, s.GetString());
}
55 56
SimpleString::~SimpleString(void) 57
{
58 59
}
60 61
delete Buffer;
//---------------------------------------------------------------------------62
//--- Operator overload support 63
void SimpleString::Append(const char* s) 64
{
65 66 67 68 69 70 71
Length += strlen(s); char *tmps=new char[Length+1]; strcpy(tmps, Buffer); strcat(tmps, s); delete Buffer; Buffer = tmps;
}
72 73
void SimpleString::Append(const SimpleString& s) 74
{
75 76 77 78 79 80 81
Length += s.GetLength(); char *tmps=new char[Length+1]; strcpy(tmps, Buffer); strcat(tmps, s.GetString()); delete Buffer; Buffer = tmps;
}
82 83
//////////////////////////////////////////////////////////////////// /////////// 84
/// Exception 85
//---------------------------------------------------------------------------86
//--- Specific Implementation 87
void Exception::PrintException(void) const 88
{
89 90 91 92 93 94
fprintf(stderr, "%s", Msg.GetString()); if ( ErrNo != 0 ) { errno = ErrNo; perror("-- Error");
95
} else
96
printf("\n");
97
}
98 99
//////////////////////////////////////////////////////////////////// /////////// 100
/// HostAddress 101
//---------------------------------------------------------------------------102
//--- Constructors & Destructors 103
HostAddress::HostAddress(const char* Name, ENetwork network) 104
{
105 106 107 108 109 110
switch ( network ) { case eIPv4: {
long s_addr; int port = 0;
111 112 113
if ( Name != 0 ) { char *portname = strrchr(Name, ':');
114
if ( portname != 0
&&
(port = atoi(portname+1)) >
0 ) 115 *portname = 0;
116
struct hostent *host = gethostbyname(Name);
117
if ( host == NULL )
118
throw NetDNSException(SimpleString("gethostbyname [") + Name + "]"); 119
s_addr = *reinterpret_cast
120 121
} else
122 123 124 125 126
s_addr = INADDR_ANY; struct sockaddr_in *addr = new struct sockaddr_in(); addr->sin_family = network; addr->sin_port = htons(port);
addr->sin_addr.s_addr = s_addr;
127
Addr = reinterpret_cast<struct sockaddr*>(addr);
128
break;
129
}
130
case eIPv6:
131
{
132
struct sockaddr_in6 *addr = new struct sockaddr_in6();
133
addr->sin6_family = network;
134
addr->sin6_port = 0;
135
if ( Name == 0 )
136
Name = "0::0";
137
if ( inet_pton(eIPv6, Name, &addr->sin6_addr) == 0 )
138
throw NetConversionException(SimpleString("inet_pton failed 139
[") + Name + "]"); Addr = reinterpret_cast<struct sockaddr*>(addr);
140
break;
141
}
142
default :
143
throw Exception("Network type not supported", ENOTSUP);
144 145 146
} Network = network;
}
147 148
HostAddress::HostAddress(HostAddress& Address) 149
{
150 151 152 153 154
switch ( Network ) { case eIPv4: { Network = Address.Network;
155
struct sockaddr_in *addr = new struct sockaddr_in();
156
memcpy(addr, Address.Addr, sizeof(*addr));
157
Addr = reinterpret_cast<struct sockaddr*>(addr);
158
break;
159
}
160
case eIPv6:
161
{
162
Network = Address.Network;
163
struct sockaddr_in6 *addr = new struct sockaddr_in6();
164
memcpy(addr, Address.Addr, sizeof(*addr));
165
Addr = reinterpret_cast<struct sockaddr*>(addr);
166
break;
167
}
168 169
}
}
170 171
HostAddress::~HostAddress(void) 172
{
173 174
delete Addr;
}
175 176
//---------------------------------------------------------------------------177
//--- Specific Implementation 178
void HostAddress::SetPort(int Port) 179
{
180 181 182 183 184
switch ( Network ) { case eIPv4: { struct sockaddr_in *inet = reinterpret_cast<struct
sockaddr_in*>(Addr); 185 inet->sin_port = htons(Port);
186
break;
187 188 189 190
} case eIPv6: { struct sockaddr_in6 *inet6 = reinterpret_cast<struct
sockaddr_in6*>(Addr); 191 192
inet6->sin6_port = htons(Port);
break;
193
}
194 195
}
}
196 197
int HostAddress::GetPort(void) const 198
{
199 200 201
switch ( Network ) { case eIPv4: return (reinterpret_cast<struct
sockaddr_in*>(Addr))->sin_port; 202 case eIPv6: return (reinterpret_cast<struct sockaddr_in6*>(Addr))->sin6_port; 203 204
}
}
205 206
int HostAddress::GetSize(void) const 207
{
208 209 210
switch ( Network ) { case eIPv4: return sizeof(struct sockaddr_in);
211
case eIPv6: return sizeof(struct sockaddr_in6);
212 213
}
}
214 215
int HostAddress::operator ==(HostAddress& Address) const 216
{
217 218
if ( Network != Address.Network ) return 0;
219 220 221
switch ( Network ) { case eIPv4:
222
case eIPv6: return (memcmp(Addr, Address.Addr, GetSize()) == 0); 223 default: return 0;
224
}
225
}
226 227
const char* HostAddress::GetHost(bool byName) 228
{
229 230 231 232 233
switch ( Network ) { case eIPv4: { char *name;
234
struct sockaddr_in *inet = reinterpret_cast<struct sockaddr_in*>(Addr); 235 236
if ( byName )
237
{
238
char *addr = reinterpret_cast
240
struct hostent *host = gethostbyaddr(addr, size, GetNetwork()); 241 if ( host == NULL )
242
throw
NetDNSException(SimpleString("gethostbyaddr failed for [") + 243
inet_ntoa(inet->sin_addr) + "]");
244
name = host->h_name;
245
}
246
else
247
name = inet_ntoa(inet->sin_addr);
248
sprintf(HostName, "%s:%d", name, (inet->sin_port));
249
break;
250 251 252 253
} case eIPv6: { struct sockaddr_in6 *inet6 = reinterpret_cast<struct
sockaddr_in6*>(Addr); 254 255 256
inet_ntop(GetNetwork(), Addr, HostName, MaxHostName); char TempS[10];
sprintf(TempS, ":%d", inet6->sin6_port);
257
strncat(HostName, TempS, MaxHostName);
258
break;
259
}
260
default: strncpy(HostName, "
} HostName[MaxHostName-1] = 0; return HostName;
}
265 266
//////////////////////////////////////////////////////////////////// /////////// 267
/// TextMessage 268
//---------------------------------------------------------------------------269
//--- Constructors & Destructors 270
TextMessage::TextMessage(unsigned short Bytes) 271
{
272 273 274
Buffer = new char[Bytes]; Available = Size = Bytes;
}
275 276
TextMessage::TextMessage(const char* Msg, unsigned short Len) 277
{
278 279 280 281 282 283
if ( Len == 0 ) Len = strlen(Msg)+1; Buffer = new char[Len]; memcpy(Buffer, Msg, Len); Available = Size = Len;
}
284 285 286
TextMessage::~TextMessage(void) 287
{
288
delete Buffer;
289
}
290 291
//---------------------------------------------------------------------------292
//--- Operator overload support 293
void TextMessage::SetString(const char* str, int len) 294
{
295 296
if ( len <= 0 ) len = strlen(str)+1;
297 298 299
if ( len >= Available ) { delete Buffer;
300
Buffer = new char[len];
301
Available = len;
302 303 304 305
} Size = len; strcpy(Buffer, str);
}
306 307
void TextMessage::Append(const char* str, int len) 308
{
309 310
if ( len <= 0 ) len = strlen(str);
311 312 313
if ( Size+len > Available ) { char *B = new char[Size+len];
314
strcpy(B, Buffer);
315
delete Buffer;
316
Buffer = B;
317
Available = Size+len;
318 319 320 321
}
322
} Size += len; strcat(Buffer, str);
323
//---------------------------------------------------------------------------324
//--- Specific Implementation 325
char *TextMessage::Wrap(int& Bytes) const 326
{
327 328 329 330 331
Bytes = Size; char *data = new char[Size]; strcpy(data, Buffer); return data;
}
332 333
bool TextMessage::Unwrap(char *Data, int Bytes, int MsgNum) 334
{
335 336
if ( MsgNum > 1 ) Append(Data, Bytes-1);
337
else 338 339 340
SetString(Data, Bytes); return reinterpret_cast
}
341 342
//////////////////////////////////////////////////////////////////// /////////// 343
/// Socket 344
//---------------------------------------------------------------------------345
//--- Constructors & Destructors 346
Socket::Socket(ENetwork Network, EProtocol Protocol) 347
{
348 349 350 351
SD = socket(Network, Protocol, 0); if ( SD < 0 ) throw NetException("Could not create socket");
}
352 353
Socket::Socket(Socket& sock) 354
{
355
356 357 358 359 360 361
int err; socklen_t size=sizeof(err); if ( getsockopt(SD, SOL_SOCKET, SO_ERROR, &err, &size) != 0 ) throw NetException("Socket error"); if ( (SD = dup(sock.SD)) < 0 ) throw FileException("Can't copy socket");
}
362 363
Socket::~Socket(void) 364
{
365 366 367 368 369
if ( close(SD) != 0 ) throw FileException("Can't close socket"); cout << "Server socket closed" << endl;
370
}
371 372
//---------------------------------------------------------------------------373
//--- Specific Implementation 374
void Socket::Bind(HostAddress& Addr) 375
{
376 377 378
if ( bind(SD, Addr.GetAddress(), Addr.GetSize()) != 0 ) throw NetConnectException("Could not bind socket");
}
379 380
int 381
Socket::Send(Message& Msg, int Options) const
{
382 383 384 385 386 387 388
int bytes; char *buf = Msg.Wrap(bytes); bytes = send(SD, buf, bytes, Options); delete buf; if ( bytes < 0 ) throw NetIOException("Could not send message"); return bytes;
389
}
390 391
int 392
Socket::Send(HostAddress& Addr, Message& Msg, int Options)
{
393 394 395
int bytes; char *buf = Msg.Wrap(bytes); bytes = sendto(SD, buf, bytes, Options, Addr.GetAddress(),
396 Addr.GetSize()); 397 398
delete buf; if ( bytes < 0 ) throw NetIOException("Could not send directed message");
399 400
return bytes;
}
401 402
int
Socket::Receive(Message& Msg, int Options) const
{
const int BufferSize = 65536;
403 404 405 406 407
bool done; int bytes, cnt=0; char *buf = new char[BufferSize]; do
408 409
{ bytes = recv(SD, buf, BufferSize, Options);
410
if ( bytes < 0 )
411
{
412
delete buf;
413
throw NetIOException("Could could get message");
414
}
415
cnt++;
416
done = Msg.Unwrap(buf, bytes, cnt);
417 418 419 420 421
}
422
} while ( !done ); delete buf; return bytes;
423
int Socket::Receive(HostAddress& Addr, Message& Msg, int Options) const 424
{
425 426 427 428 429
const int BufferSize = 65536; socklen_t len = Addr.GetSize(); bool done; int bytes, cnt=0; char *buf = new char[BufferSize]; do
430 431
{ bytes = recvfrom(SD, buf, BufferSize, Options,
432 Addr.GetAddress(),
if ( bytes < 0 )
433
{
434
delete buf;
435
throw NetIOException("Could could get message");
436
}
437
cnt++;
438
done = Msg.Unwrap(buf, bytes, cnt);
439 440 441 442 443
&len);
} while ( !done ); delete buf; return bytes;
}
444 445
//---------------------------------------------------------------------------446
//--- Class configuration (CRUD) 447
void Socket::PermitRoute(bool Setting) 448
{
449 450
int val = (Setting == 0); if ( setsockopt(SD, SOL_SOCKET, SO_DONTROUTE, &val, sizeof(val))
!= 451 0 ) 452
}
453 454
throw NetConfigException("Socket Option: set DONTROUTE");
void Socket::KeepAlive(bool Setting) 455
{
456
int val = (Setting != 0);
457
if ( setsockopt(SD, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) != 458
0 ) throw NetConfigException("Socket Option: set KEEPALIVE");
459
}
460 461
void Socket::ShareAddress(bool Setting) 462
{
463 464
int val = (Setting != 0); if ( setsockopt(SD, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))
!= 465 0 ) 466
throw NetConfigException("Socket Option: set REUSEADDR");
}
467 468
int 469
Socket::GetReceiveSize(void)
{
470 471 472 473 474 475
int val; socklen_t size=sizeof(val); if ( getsockopt(SD, SOL_SOCKET, SO_RCVBUF, &val, &size) != 0 ) throw NetConfigException("Socket Option: get RCVBUF"); return val;
}
476 477
void Socket::SetReceiveSize(int Bytes) 478
{
479
if ( setsockopt(SD, SOL_SOCKET, SO_RCVBUF, &Bytes, sizeof(Bytes)) 480 481
!= 0 )
throw NetConfigException("Socket Option: set RCVBUF");
}
482 483
int 484
Socket::GetSendSize(void)
{
485 486
int val; socklen_t size=sizeof(val);
487 488
if ( getsockopt(SD, SOL_SOCKET, SO_SNDBUF, &val, &size) != 0 ) throw NetConfigException("Socket Option: get SNDBUF");
489 490
return val;
}
491 492
void Socket::SetSendSize(int Bytes) 493
{
494
if ( setsockopt(SD, SOL_SOCKET, SO_SNDBUF, &Bytes, sizeof(Bytes)) 495
!= 0 )
throw NetConfigException("Socket Option: set SNDBUF");
496
}
497 498
int 499
Socket::GetMinReceive(void)
{
500 501 502 503
int val; socklen_t size=sizeof(val); if ( getsockopt(SD, SOL_SOCKET, SO_RCVLOWAT, &val, &size) != 0 ) throw NetConfigException("Socket Option: get RCVLOWAT");
504 505
return val;
}
506 507
void Socket::SetMinReceive(int Bytes) //---Not yet implemented in Linux 508
{
509
if ( setsockopt(SD, SOL_SOCKET, SO_RCVLOWAT, &Bytes, sizeof(Bytes)) 510 511
!= 0 )
throw NetConfigException("Socket Option: set RCVLOWAT");
}
512 513
int 514
Socket::GetMinSend(void)
{
515 516 517 518 519
int val; socklen_t size=sizeof(val); if ( getsockopt(SD, SOL_SOCKET, SO_SNDLOWAT, &val, &size) != 0 ) throw NetConfigException("Socket Option: get SNDLOWAT");
520
return val;
}
521 522
void Socket::SetMinSend(int Bytes) //---Not yet implemented in Linux 523
{
524
if ( setsockopt(SD, SOL_SOCKET, SO_SNDLOWAT, &Bytes, sizeof(Bytes)) != 0 ) 525 526
throw NetConfigException("Socket Option: set SNDLOWAT");
}
527 528
struct timeval Socket::GetReceiveTimeout(void) 529
{
530 531 532 533 534 535
struct timeval val; socklen_t size=sizeof(val); if ( getsockopt(SD, SOL_SOCKET, SO_RCVTIMEO, &val, &size) != 0 ) throw NetConfigException("Socket Option: get RCVTIMEO"); return val;
}
536 537
void Socket::SetReceiveTimeout(struct timeval& val) //---Not yet implemented in Linux 538
{
539
if ( setsockopt(SD, SOL_SOCKET, SO_RCVTIMEO, &val, sizeof(val)) 540 541
!= 0 )
throw NetConfigException("Socket Option: set RCVTIMEO");
}
542 543
struct timeval Socket::GetSendTimeout(void) 544
{
545 546 547 548 549 550
}
551
struct timeval val; socklen_t size=sizeof(val); if ( getsockopt(SD, SOL_SOCKET, SO_SNDTIMEO, &val, &size) != 0 ) throw NetConfigException("Socket Option: get SNDTIMEO"); return val;
552
void Socket::SetSendTimeout(struct timeval& val) //---Not yet implemented in Linux 553
{
554
if ( setsockopt(SD, SOL_SOCKET, SO_SNDTIMEO, &val, sizeof(val)) 555
!= 0 )
throw NetConfigException("Socket Option: set SNDTIMEO");
556
}
557 558
ENetwork Socket::GetType(void) 559
{
560 561 562 563
int val; socklen_t size=sizeof(val); if ( getsockopt(SD, SOL_SOCKET, SO_TYPE, &val, &size) != 0 ) throw NetConfigException("Socket Option: get TYPE");
564 565
return (ENetwork)val;
}
566 567
int 568
Socket::GetTTL(void)
{
569 570 571 572 573
int val; socklen_t size=sizeof(val); if ( GetType() == eIPv4 ) { if ( getsockopt(SD, SOL_IP, IP_TTL, &val, &size) != 0 )
574
throw NetConfigException("IP Option: get TTL");
575 576 577 578
} else if ( GetType() == eIPv6 ) { if ( getsockopt(SD, SOL_IPV6, IPV6_UNICAST_HOPS, &val,
&size) 579
throw NetConfigException("IP Option: get
580 581 582
}
583 584
!= 0 )
} return val;
void Socket::SetTTL(int Hops) 585
{
586 587 588
if ( GetType() == eIPv4 ) { if ( setsockopt(SD, SOL_IP, IP_TTL, &Hops, sizeof(Hops)) !=
0 589) throw NetConfigException("IP Option: set TTL");
590 591 592 593
} else if ( GetType() == eIPv6 ) { if ( setsockopt(SD, SOL_IPV6, IPV6_UNICAST_HOPS, &Hops,
sizeof(Hops)) != 0 ) 594 throw NetConfigException("IP Option: set
595 596
}
}
597 598
int 599
Socket::GetError(void)
{
600 601 602 603 604 605
int val; socklen_t size=sizeof(val); if ( getsockopt(SD, SOL_SOCKET, SO_ERROR, &val, &size) != 0 ) throw NetConfigException("Socket Option: get ERROR"); return val;
}
606 607
//////////////////////////////////////////////////////////////////// /////////// 608
/// SocketStream 609
//---------------------------------------------------------------------------610
//--- Class configuration (CRUD) 611 612
int 613
SocketStream::GetMaxSegmentSize(void)
{
614 615 616
int val; socklen_t size=sizeof(val);
617 618 619
if ( getsockopt(SD, SOL_TCP, TCP_MAXSEG, &val, &size) != 0 ) throw NetConfigException("Socket Option: get TCP_MAXSEG"); return val;
}
620 621
void SocketStream::SetMaxSegmentSize(short Bytes) 622
{
623
if ( setsockopt(SD, SOL_TCP, TCP_MAXSEG, &Bytes, sizeof(Bytes)) 624 625
!= 0 )
throw NetConfigException("Socket Option: set TCP_MAXSEG");
}
626 627
void SocketStream::DontDelay(bool Setting) 628
{
629
if ( setsockopt(SD, SOL_TCP, TCP_NODELAY, &Setting, sizeof(Setting)) != 0 ) 630 631
throw NetConfigException("Socket Option: DONTDELAY ");
}
632 633
//////////////////////////////////////////////////////////////////// /////////// 634
/// SocketServer 635
//---------------------------------------------------------------------------636
//--- Constructors & Destructors 637
SocketServer::SocketServer(int Port, ENetwork Network, int QLen): SocketStream(Network) 638 {
639 640 641 642 643 644 645 646 647
type = eNone; task_fn = 0; HostAddress Addr(0); Addr.SetPort(Port); Bind(Addr); if ( listen(SD, QLen) != 0 ) throw NetConnectException("Listen"); struct sigaction act;
648 649 650 651 652
memset(&act, 0 , sizeof(act)); act.sa_handler = SigChild; act.sa_flags = SA_NOCLDSTOP; if ( sigaction(SIGCHLD, &act, 0) != 0 ) throw Exception("Sigaction -- processes");
653
}
654 655
SocketServer::SocketServer(HostAddress& Me, int QLen): SocketStream(Me.GetNetwork()) 656 {
657 658 659 660 661
type = eNone; task_fn = 0; Bind(Me); if ( listen(SD, QLen) != 0 ) throw NetConnectException("Could not convert to listening
socket"); 662 663 664 665 666 667
struct sigaction act; memset(&act, 0 , sizeof(act)); act.sa_handler = SigChild; act.sa_flags = SA_NOCLDSTOP; if ( sigaction(SIGCHLD, &act, 0) != 0 ) throw Exception("Sigaction -- processes");
668
}
669 670
SocketServer::~SocketServer(void) 671
{
672
}
673 674
//---------------------------------------------------------------------------675
//--- Specific Implementation 676
void SocketServer::Accept(void (*Server)(const Socket&)) 677
{
678 679
/* 680
int client = accept(SD, 0, 0); 681
if ( client < 0 ) 682
throw NetConnectException("Problems with accepting a
connection"); 683
switch ( type ) 684
{ 685
case eCallback: 686
case eProcess: 687
case eThread: break; 688
} 689
(*Server)(Socket(client)); 690
*/ 691 692 693 694
socklen_t size; int client, pid;
695 696
cout << "SocketServer::Accept()" << endl;
697 698 699 700
for (;;) { client = accept(SD, 0, 0);
701 702
if ( client < 0 ) continue; //throw NetConnectException("Problems with accepting a
connection"); 703 704 705 706 707
if ( (pid = fork()) == 0 ) {
cout << "I am here inside fork." << endl; /*
708
if ( close(SD) != 0 ) 709
throw FileException("Accept: Can't close socket"); 710
*/ 711 712
(*Server)(Socket(client));
713
cout << "Here fork is finished" << endl;
714 715 716
exit(0);
717
}
718
else if ( pid > 0 ) { close(client); cout << "Client socket << endl;} else
closed." 719 720
throw NetConnectException("fork() failed");
721 722
cout << "back into the loop" << endl;
723 724 725
}
726 727
}
728 729
void SocketServer::Accept(HostAddress& Addr, void (*Server)(const Socket&)) 730 {
731 732
cout << "SocketServer::Accept() overloaded not implemented" << endl; 733 /* 734
switch ( type ) 735
{ 736
case eCallback: 737
case eProcess: 738
case eThread: break; 739
} */ 740
/* 741
socklen_t size; 742
int client, pid; 743 744
for (;;) 745
{ 746
size
= Addr.GetSize();
747
client = accept(SD, Addr.GetAddress(), &size); 748 749
if ( client < 0 ) 750
throw NetConnectException("Problems with accepting a connection"); 751 752 753
if ( (pid = fork()) == 0 ) 754
{
cout << "I am here inside fork." << endl;
755
//if ( close(SD) != 0 ) 756
//
throw FileException("Accept: Can't close socket");
757
(*Server)(Socket(client)); 758
cout << "Here fork is finished" << endl; 759
} 760
else if ( pid > 0 ) { close(client); cout << "Client socket
closed." << endl;} 761
else 762
throw NetConnectException("fork() failed"); 763 764
cout << "back into the loop" << endl; 765 766
} 767
/* 768
(*Server)(Socket(client)); 769
*/ 770 771 772
}
773 774
//---------------------------------------------------------------------------775
//--- Class configuration (CRUD) 776
void SocketServer::RegTask(void (*FN)(Socket& socket, HostAddress& addr)) 777 {
778
}
779
780 781
//////////////////////////////////////////////////////////////////// /////////// 782
/// SocketClient 783
//---------------------------------------------------------------------------784
//--- Constructors & Destructors 785
SocketClient::SocketClient(HostAddress& Host, ENetwork Network): SocketStream(Network) 786 {
787 788
Connect(Host);
}
789 790
//---------------------------------------------------------------------------791
//--- Specific Implementation 792
void SocketClient::Connect(HostAddress& Address) 793
{
794 795 796
if ( connect(SD, Address.GetAddress(), Address.GetSize()) != 0 ) throw NetConnectException("Connect");
}
797 798 799
//////////////////////////////////////////////////////////////////// /////////// 800
/// Datagram 801
//---------------------------------------------------------------------------802
//--- Constructors & Destructors 803 804
Datagram::Datagram(HostAddress& Me, ENetwork Network, EProtocol Protocol): 805
Socket(Network, Protocol)
{
806 807
Bind(Me);
}
808 809
Datagram::Datagram(ENetwork Network, EProtocol Protocol): Socket(Network, Protocol)
810
{}
811 812
//---------------------------------------------------------------------------813
//--- Private class configuration (CRUD) 814 815
void Datagram::SetTOS(bool Setting, int Val) 816
{
817 818 819 820
int tos; socklen_t size=sizeof(tos); if ( getsockopt(SD, SOL_IP, IP_TOS, &tos, &size) != 0 ) throw NetConfigException("Socket Option: get IP_TOS");
821 822 823
if ( Setting != 0 ) tos |= Val; else
824 825 826 827
tos &= ~Val; if ( setsockopt(SD, SOL_IP, IP_TOS, &tos, sizeof(tos)) != 0 ) throw NetConfigException("Socket Option: set IP_TOS");
}
828 829
//---------------------------------------------------------------------------830
//--- Class configuration (CRUD) 831 832
void Datagram::MinimizeDelay(bool Setting) 833
{
834 835
SetTOS(Setting, IPTOS_LOWDELAY);
}
836 837
void Datagram::MaximizeThroughput(bool Setting) 838
{
839 840
SetTOS(Setting, IPTOS_THROUGHPUT);
}
841 842
void Datagram::MaximizeReliability(bool Setting)
843
{
844 845
SetTOS(Setting, IPTOS_RELIABILITY);
}
846 847
void Datagram::MinimizeCost(bool Setting) 848
{
849 850
SetTOS(Setting, IPTOS_LOWCOST);
}
851 852
void Datagram::PermitFragNegotiation(EFrag Setting) 853
{
854
if ( setsockopt(SD, SOL_IP, IP_MTU_DISCOVER, &Setting, sizeof(Setting)) 855
!= 0 )
throw NetConfigException("Socket Option: set MTU_DISCOVER");
856
}
857 858
//////////////////////////////////////////////////////////////////// /////////// 859
/// Broadcast 860
//---------------------------------------------------------------------------861
//--- Constructors & Destructors 862
Broadcast::Broadcast(HostAddress& Me): Datagram(Me) 863
{
864 865
const int on=1; if ( setsockopt(SD, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) !
= 0 866 867
) throw NetConfigException("Socket Option: set BROADCAST");
}
868 869
//////////////////////////////////////////////////////////////////// /////////// 870
/// MessageGroup 871
//---------------------------------------------------------------------------872
//--- Constructors & Destructors 873
MessageGroup::~MessageGroup(void) 874
{
875 876 877
HostAddress NoAddr(0, GetType()); for ( int i = 0; i < MAXGROUPS; i++ ) if ( Addr[i] != NoAddr )
878
Drop(Addr[i]);
879
}
880 881
//---------------------------------------------------------------------------882
//--- Specific Implementation 883
void MessageGroup::Connect(HostAddress& Address) 884
{
885 886
if ( connect(SD, Address.GetAddress(), Address.GetSize()) != 0 ) throw NetConnectException("Connect");
887
}
888 889
int MessageGroup::FindSlot(HostAddress& Host) 890
{
891
int slot=-1;
892 893
for ( int i = 0; i < MAXGROUPS
slot < 0; i++ )
if ( Addr[i] == Host )
894
slot = i;
895 896
&&
return slot;
}
897 898
void MessageGroup::Join(HostAddress& Address, int IFIndex) 899
{
900 901
int slot=-1; HostAddress NoAddr(0, Address.GetNetwork());
902 903 904
slot = FindSlot(NoAddr); if ( slot < 0 ) throw RangeException("Multicast table full");
905 906 907
if ( GetType() == eIPv4 ) {
struct ip_mreqn mreq;
908
bzero(&mreq, sizeof(mreq));
909
void* src = &(reinterpret_cast<struct sockaddr_in *>(Address.GetAddress())->sin_addr); 910 memcpy(&mreq.imr_multiaddr, src, sizeof(mreq.imr_multiaddr)); 911 mreq.imr_ifindex = IFIndex;
912
if ( setsockopt(SD, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) != 0 ) 913 throw NetConfigException("Socket Option: Join Multicast"); 914 915 916 917
} else if ( GetType() == eIPv6 ) {
struct ipv6_mreq mreq;
918
bzero(&mreq, sizeof(mreq));
919
void* src = &(reinterpret_cast<struct sockaddr_in *>(Address.GetAddress())->sin_addr); 920 memcpy(&mreq.ipv6mr_multiaddr, src, sizeof(mreq.ipv6mr_multiaddr)); 921 mreq.ipv6mr_interface = IFIndex;
922
if ( setsockopt(SD, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) 923
!= 0 )
throw NetConfigException("Socket Option: Join Multicast"); 924 925 926
} Addr[slot] = Address;
}
927 928
void MessageGroup::Drop(HostAddress& Address) 929
{
930
int slot=-1;
931 932 933 934 935 936 937
for ( int i = 0; i < MAXGROUPS
&&
slot < 0; i++ )
if ( Addr[i] == Address ) slot = i; if ( slot == -1 ) throw RangeException("Group not joined"); if ( GetType() == eIPv4 )
938
{
struct ip_mreq mreq; struct sockaddr_in *inet = reinterpret_cast<struct
sockaddr_in 939
*>(Addr[slot].GetAddress());
940
mreq.imr_multiaddr = inet->sin_addr;
941
mreq.imr_interface.s_addr = INADDR_ANY;
942
if ( setsockopt(SD, SOL_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) 943
!= 0 )
throw NetConfigException("Socket Option: Drop Multicast"); 944 945 946 947
} else if ( GetType() == eIPv6 ) {
struct ipv6_mreq mreq; struct sockaddr_in6 *inet6 = reinterpret_cast<struct
sockaddr_in6 948
*>(Addr[slot].GetAddress());
mreq.ipv6mr_multiaddr = inet6->sin6_addr;
949
mreq.ipv6mr_interface = INADDR_ANY;
950
if ( setsockopt(SD, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) != 0 ) 951 throw NetConfigException("Socket Option: Drop Multicast"); 952 953 954
} Addr[slot] = HostAddress();
}
955 956
//---------------------------------------------------------------------------957
//--- Class configuration (CRUD) 958 959
void MessageGroup::Loopback(bool Setting) 960
{
961 962 963 964
int val = (Setting != 0); if ( GetType() == eIPv4 ) { if ( setsockopt(SD, SOL_IP, IP_MULTICAST_LOOP, &val,
sizeof(val)) != 0 ) 965 throw NetConfigException("IP Option: set
966 967
}
968 969
else if ( GetType() == eIPv6 ) { if ( setsockopt(SD, SOL_IPV6, IPV6_MULTICAST_LOOP, &val, != 0 )
sizeof(val)) 970
throw NetConfigException("IP Option: set
971 972
}
}
973 974
int 975
MessageGroup::GetTTL(void)
{
976 977 978 979 980
int val; socklen_t size=sizeof(val); if ( GetType() == eIPv4 ) { if ( getsockopt(SD, SOL_IP, IP_MULTICAST_TTL, &val, &size) !
= 0 981
) throw NetConfigException("IP Option: get
982 983 984 985
} else if ( GetType() == eIPv6 ) { if ( getsockopt(SD, SOL_IPV6, IPV6_MULTICAST_HOPS, &val,
&size) 986
throw NetConfigException("IP Option: get
987 988 989
!= 0 )
} return val;
}
990 991
void MessageGroup::SetTTL(int Hops) 992
{
993 994 995
if ( GetType() == eIPv4 ) { if ( setsockopt(SD, SOL_IP, IP_MULTICAST_TTL, &Hops,
sizeof(Hops)) 996
throw NetConfigException("IP Option: set
997 998 999
!= 0 )
} else if ( GetType() == eIPv6 )
1000
{ if ( setsockopt(SD, SOL_IPV6, IPV6_MULTICAST_HOPS, &Hops,
sizeof(Hops)) 1001
throw NetConfigException("IP Option: set
1002 1003
}
!= 0 )
}