FX::QBlkSocket Class Reference
[Synchronous i/o devices]

#include <QBlkSocket.h>

Inheritance diagram for FX::QBlkSocket:

FX::QIODeviceS FX::QIODevice List of all members.

Detailed Description

A synchronous TCP or UDP network socket (Qt compatible).

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.

Warning:
Do not do multiple reads from multiple threads at the same time. Nor multiple writes from multiple threads (you can read in one thread and write in another concurrently fine). This is due to a limitation in the Windows implementation.

Differences from Qt:

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.

Usage:

To create a TCP server socket on port 12345:

QBlkSocket server(QBlkSocket::Stream, (FXushort) 12345);
server.create(IO_ReadWrite);
To wait for someone to connect to your TCP server socket:
FXPtrHold<QBlkSocket> transport=server.waitForConnection();
FXProcess::threadPool().dispatch(Generic::BindFuncN(clientHandler, transport));
transport=0;
See also:
FX:FXNetwork

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 QHostAddressaddress () const
FXushort port () const
QHostAddress peerAddress () const
FXushort peerPort () const
const QHostAddressrequestedAddress () 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 FXACLpermissions () 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)
QBlkSocketwaitForConnection (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 FXStreamoperator<< (FXStream &s, QIODevice &i)
FXAPI FXStreamoperator>> (FXStream &s, QIODevice &i)


The documentation for this class was generated from the following file:
(C) 2002-2009 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Nov 20 18:37:34 2009 for TnFOX by doxygen v1.4.7