#include <QBlkSocket.h>
Inheritance diagram for FX::QBlkSocket:
This is a synchronous network socket class capable of providing a TCP connection or UDP packet-based transfers. Synchronous means that unlike most socket implementations there is no posting of messages to notify you of events - instead a much simpler and elegant structure is required of having a unique thread wait on input and it can handle and/or dispatch incoming data.
It is also almost API compatible with Qt's QSocketDevice which is Qt's core socket class. Unlike QSocketDevice, QBlkSocket can only behave in a blocking fashion.
Furthermore, QBlkSocket provides a full IPv6 interface as well as IPv4 facilities. All you need to do is set an IPv6 address in FX:QHostAddress and the rest is taken care of for you.
The send and receive buffer sizes are important. If the send buffer size becomes too full to allow insertion of a writeBlock(), writeBlock() will stall until enough data has been sent. This may take seconds and occasionally minutes. The receive buffer size is also important because it limits the maximum data length you can pass to readBlock() which will never return more than readBufferSize() bytes. On Win32, the default read and write buffer sizes appear to be 8192 bytes which is a little small. On Linux on FreeBSD, they are a much more reasonable 49152 bytes.
To create the server end of a socket, instantiate a QBlkSocket just as type and optionally port (if port is zero, it chooses any free port which isn't really useful for server sockets) and call create(). This will bind the socket to any local network adaptor which is chosen by whichever adaptor the incoming connection is using and can be retrieved after connection by address() and port(). If your server socket is for localhost communication only you should use the other constructor specifying the loopback address 127.0.0.1
or ::1 (QHOSTADDRESS_LOCALHOST) - this on many systems internally optimises the connection, making it much faster. Lastly if you want a client socket connecting to some server socket, specify the address and port you want to connect to and call open().
Stream type can be either QBlkSocket::Stream or QBlkSocket::Datagram. The former uses TCP over IP and is a connection-based reliable full-duplex general-purpose data transport protocol. The latter uses UDP over IP and is a connection-less unreliable packet protocol - unreliable means your packets may not receive their destination nor in the same order as sending, however its ability to send status updates much more efficiently than TCP guarantees its usefulness.
For stream-based server sockets you should create() the socket in your monitoring thread, then call waitForConnection() which upon a client connect, returns a new instance of the server socket with a connection to the client. You should at this stage launch another thread to handle monitoring that connection and return to waitForConnection() again.
For datagram-based server sockets, you also call create() - however now you simply try reading from the socket, or else call FX::QIODeviceS::waitForData() if you'd like to poll it. When the read succeeds, peerAddress() and peerPort() will return the source of the datagram until the next read is performed.
Sending data via a datagram-based socket uses the destination address and port as specified in the constructor or to whatever setRequestedAddressAndPort(). If you would like to send data to an arbitrary address and port, use the other writeBlock() overload. Note that you can neither send nor receive any datagrams larger than maxDatagramSize().
A full discussion of the issues surrounding TCP, UDP, IPv4 and IPv6 is beyond the scope of this class documentation, but there are plenty of man pages, MSVC help files, books and RFC's available. Note that by default socket linger is enabled and set to five seconds.
Default security on sockets is full public access and you cannot change this. If you want to control security, consider using FX::QPipe which is more efficient anyway.
Lastly FX::FXConnectionLostException with error code FXEXCEPTION_CONNECTIONLOST is thrown should a connection unexpectedly terminate. You will probably want to trap this for client sockets - for server sockets, you just destroy the instance.
First off, as usual, errors are returned as exceptions rather than by error(). Secondly, a lot of the complexity in QSocketDevice can be avoided as this socket always blocks - thus some API's return default values. I've also removed the methods allowing direct manipulation of the socket handle as code should need to know nothing about it (and this is the biggest break from QSocketDevice's API). Lastly, I've extended the API where it makes sense to make it easier to use.
To create a TCP server socket on port 12345:
QBlkSocket server(QBlkSocket::Stream, (FXushort) 12345); server.create(IO_ReadWrite);
FXPtrHold<QBlkSocket> transport=server.waitForConnection(); FXProcess::threadPool().dispatch(Generic::BindFuncN(clientHandler, transport)); transport=0;
Definition at line 144 of file QBlkSocket.h.
Public Types | |
Stream | |
Datagram | |
enum | Type { Stream, Datagram } |
typedef FXfval | Offset |
Default | |
Unix | |
MacOS | |
MSDOS | |
NoTranslation | |
UTF8 | |
UTF16 | |
UTF16LE | |
UTF32 | |
UTF32LE | |
enum | CRLFType { Default, Unix, MacOS, MSDOS } |
enum | UnicodeType { NoTranslation, UTF8, UTF16, UTF16LE, UTF32, UTF32LE } |
Public Member Functions | |
QBlkSocket (Type type=Stream, FXushort port=0) | |
QBlkSocket (const QHostAddress &addr, FXushort port, Type type=Stream) | |
QBlkSocket (const FXString &addr, FXushort port, Type type=Stream) | |
QBlkSocket (QBlkSocket &o) | |
~QBlkSocket () | |
Type | type () const |
void | setType (Type type) |
const QHostAddress & | address () const |
FXushort | port () const |
QHostAddress | peerAddress () const |
FXushort | peerPort () const |
const QHostAddress & | requestedAddress () const |
FXushort | requestedPort () const |
void | setRequestedAddressAndPort (const QHostAddress &reqAddr, FXushort port) |
bool | isUnique () const |
void | setUnique (bool a) |
FXuval | receiveBufferSize () const |
void | setReceiveBufferSize (FXuval newsize) |
FXuval | sendBufferSize () const |
void | setSendBufferSize (FXuval newsize) |
FXuval | maxDatagramSize () const |
FXint | maxPending () const |
void | setMaxPending (FXint newp) |
bool | listen (int newp) |
bool | addressReusable () const |
void | setAddressReusable (bool newar) |
bool | keepAlive () const |
void | setKeepAlive (bool newar) |
FXint | lingerPeriod () const |
void | setLingerPeriod (FXint period) |
bool | usingNagles () const |
void | setUsingNagles (bool newar) |
bool | connected () const |
bool | create (FXuint mode=IO_ReadWrite) |
bool | open (FXuint mode=IO_ReadWrite) |
void | close () |
void | flush () |
bool | reset () |
FXfval | size () const |
FXDEPRECATEDEXT FXfval | bytesAvailable () const |
virtual const FXACL & | permissions () const |
FXuval | readBlock (char *data, FXuval maxlen) |
FXuval | writeBlock (const char *data, FXuval maxlen) |
FXuval | writeBlock (const char *data, FXuval maxlen, const QHostAddress &addr, FXushort port) |
int | ungetch (int) |
QBlkSocket * | waitForConnection (FXuint waitfor=FXINFINITE) |
FXDEPRECATEDEXT bool | blocking () const |
FXDEPRECATEDEXT void | setBlocking (bool) |
FXDEPRECATEDEXT FXuval | waitForMore (int msecs, bool *timeout=0) |
virtual bool | isSynchronous () const |
virtual void | truncate (FXfval) |
virtual FXfval | at () const |
virtual bool | at (FXfval) |
virtual bool | atEnd () const |
virtual FXuval | readBlockFrom (char *data, FXuval maxlen, FXfval pos) |
FXuval | readBlockFrom (FXuchar *data, FXuval maxlen, FXfval pos) |
virtual FXuval | writeBlockTo (FXfval pos, const char *data, FXuval maxlen) |
FXuval | writeBlockTo (FXfval pos, const FXuchar *data, FXuval maxlen) |
FXuint | flags () const |
FXuint | mode () const |
FXuint | state () const |
CRLFType | crlfFormat () const |
void | setCRLFFormat (CRLFType type) |
UnicodeType | unicodeTranslation () const |
void | setUnicodeTranslation (UnicodeType type) |
bool | isBuffered () const |
bool | isRaw () const |
bool | isTranslated () const |
bool | isUTF16Translated () const |
bool | isUTF32Translated () const |
bool | isReadable () const |
bool | isWriteable () const |
bool | isWritable () const |
bool | isReadWrite () const |
bool | isClosed () const |
bool | isInactive () const |
bool | isOpen () const |
virtual void | setPermissions (const FXACL &) |
FXuval | readBlock (FXuchar *data, FXuval maxlen) |
FXuval | writeBlock (const FXuchar *data, FXuval maxlen) |
virtual FXuval | readLine (char *data, FXuval maxlen) |
virtual int | getch () |
virtual int | putch (int c) |
FXfval | shredData (FXfval offset, FXfval len=(FXfval)-1) |
Static Public Member Functions | |
static bool | waitForData (QIODeviceS **signalled, FXuint no, QIODeviceS **list, FXuint waitfor=FXINFINITE) |
static FXuint | waitForDataMax () throw () |
static UnicodeType | determineUnicodeType (FXuchar *data, FXuval len) throw () |
static FXuval | applyCRLF (FXuchar *FXRESTRICT output, const FXuchar *FXRESTRICT input, FXuval outputlen, FXuval &inputlen, CRLFType crlftype=Default, UnicodeType utftype=NoTranslation) |
static FXuval | removeCRLF (FXuchar *FXRESTRICT output, const FXuchar *FXRESTRICT input, FXuval outputlen, FXuval &inputlen, UnicodeType utftype=NoTranslation) |
Protected Member Functions | |
void | setFlags (int f) |
void | setMode (int m) |
void | setState (int s) |
Protected Attributes | |
FXfval | ioIndex |
Friends | |
FXAPI FXStream & | operator<< (FXStream &s, QIODevice &i) |
FXAPI FXStream & | operator>> (FXStream &s, QIODevice &i) |