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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/*
* Copyright (C) 2007-2023 Xagasoft, All rights reserved.
*
* This file is part of the libbu++ library and is released under the
* terms of the license contained in the file LICENSE.
*/
#ifndef BU_SOCKET_TCP_H
#define BU_SOCKET_TCP_H
#include <stdint.h>
#include "bu/config.h"
#include "bu/socket.h"
#include "bu/string.h"
#include "bu/exceptionbase.h"
namespace Bu
{
subExceptionDeclBegin( SocketTcpException );
enum {
cRead,
cWrite,
cBadRead,
cClosed,
cTimeout
};
subExceptionDeclEnd();
/**
* Network socket stream class. This class provides a mechanism for
* communicating over a network using TCP/IP. It will provide other low
* level protocol and addressing support later on, but for now it's just
* standard STREAM TCP/IP sockets.
*
* Unlike system sockets, these sockets are opened by default in
* non-blocking mode, you can specify your own timeout for opening a socket,
* and a number of non-fatal error messages have been automatically handled
* and treated as standard no-data-available-yet situations on read.
*
* Please note that there is a condition that will occur eventually (at
* least on *nix systems) that will trigger a SIGPIPE condition. This
* will terminate your program immediately unless handled properly. Most
* people doing any connections with SocketTcp will want to put this in
* their program somewhere before they use it:
*@code
#include <signal.h>
...
...
...
// sigset is deprecated
sigset( SIGPIPE, SIG_IGN ); // do this before you use a Bu::SocketTcp
// this is the modern Linux alternative
struct sigaction saIgnore;
memset( &saIgnore, 0, sizeof(struct sigaction) );
saIgnore.sa_handler = SIG_IGN;
sigaction( SIGPIPE, &saIgnore, NULL );
@endcode
* When this is done, Bu::SocketTcp will simply throw a broken pipe
* exception just like every other error condition, allowing your program
* to handle it sanely.
*
*@ingroup Serving
*@ingroup Streams
*/
class SocketTcp : public Socket
{
public:
#ifdef WIN32
typedef unsigned int handle;
#else
typedef int handle;
#endif
SocketTcp( handle nSocketTcp );
SocketTcp( const String &sAddr, int nPort, int nTimeout=30,
bool bBlocking=true );
virtual ~SocketTcp();
virtual void close();
virtual size read( void *pBuf, size nBytes );
virtual size read( void *pBuf, size nBytes,
uint32_t nSec, uint32_t nUSec=0 );
virtual size write( const void *pBuf, size nBytes );
virtual size write( const void *pBuf, size nBytes,
uint32_t nSec, uint32_t nUSec=0 );
using Stream::write;
virtual size tell();
virtual void seek( size offset );
virtual void setPos( size pos );
virtual void setPosEnd( size pos );
virtual bool isEos();
virtual bool isOpen();
virtual void flush();
virtual bool canRead();
virtual bool canWrite();
virtual bool isReadable();
virtual bool isWritable();
virtual bool isSeekable();
virtual bool isBlocking();
virtual void setBlocking( bool bBlocking=true );
virtual void setSize( size iSize );
Bu::String getAddress() const;
operator handle() const;
handle getHandle() const;
handle takeHandle();
virtual size getSize() const;
virtual size getBlockSize() const;
virtual Bu::String getLocation() const;
virtual bool getFd( int &rFdOut ) const;
private:
void setAddress();
handle nSocketTcp;
bool bActive;
bool bBlocking;
String sReadBuf;
String sAddress;
};
}
#endif
|