"Remy Lebeau (TeamB)" <
XXXX@XXXXX.COM>writes
I hope I am not making this thread go on too long - but it is an interesting
subject!
Quote
>I would have thought that they can still be used for non-blocking
>socket I/O
They can be, otherwise the BlockMode property would not exist in the first
place.
That's true, but the implementation of TBaseSocket class in the Sockets unit
doesn't seem to take into account the implications of the BlockMode property
on the validity of the code. Consider for example the method
function TBaseSocket.Receiveln(const eol: string): string;
As I see it, the method contains 2 conceptual errors:
Error 1) Since the code contains a call of Recv inside a loop, it probably
won't work if the socket is non-blocking, because it would not wait for the
completion of one Recv operation before proceeding to the next Recv
operation. Therefore the code should either check the blocking mode and
raise an exception if it is non-blocking, or else it should correctly handle
the non-blocking socket case and include some code to wait for the
completion of the Recv operation.
Error 2) The function's code previews ("peeks") the incoming stream in
chunks of 511 bytes or less, and searches the chunk for the termination
string "eol". If the termination string is found, then the function receives
the characters up to and including the end of the termination string and
terminates the loop, and if it isn't found, the function receives the whole
chunk and continues the loop. Thus 2 possible cases are considered: the
chunk of data in the socket's buffer either contains the termination string,
or it doesn't. But there is a third case not considered: the termination
string straddles 2 successive chunks. Should this case arise, the code would
not identify the end of string condition and the loop would not terminate
correctly.
All this leads me to think: wouldn't it be much better, and easier, if
Delphi simply provided a library of functions in Pascal syntax for the
Berkeley socket functions in the Windows API, as listed in the MS SDK help
files under "socket functions", and let the developer worry about thread
creation etc.? The library would be easily portable to any operating system
that supports the Berkeley socket model - i.e all the major OS's. Granted, a
developer could use the WinSock API functions directly - but the code would
be more readable and more portable if entirely in Pascal style.
It would also be nice if Delphi were to provide a library of data stream
I/O routines in Pascal syntax that support the MS asynchronous I/O model
(i.e. overlapped IO, synchronization objects, WaitForXXX functions, etc.).
These should be applicable without change to serial port data streams and
socket data streams. The conceptual model should be an abstract
time-discontinuous data stream accessed though a queued buffer. The
conceptual model should include notification of asynchronous I/O completion
by 4 methods: a) calling of an event handler b) posting a message c)
signalling a synchronization object d) calling a Windows completion routine.
The important thing is that the Delphi encapsulation should be in terms of
the abstract model, so that it can be readily ported to any OS whose API
supports asynchronous I/O. The data stream type could simply be an extended
type of file, that adds to the characteristics of the original Pascal file
type the concepts of access through a queue, asynchronous operation and
notification of completion.
I have noticed that both Java and C# provide socket routines that are
relatively close to the Berkeley socket model, and in both the socket
exposes input and output data streams that can be manipulated just like any
other data stream. If only Delphi could keep things equally simple!
EM