"Alex Fraser" <
XXXX@XXXXX.COM>writes
Quote
"Skybuck Flying" <XXXX@XXXXX.COM>writes
news:bjge6j$q2t$XXXX@XXXXX.COM...
>Hmm.. the problem remains, if the server closes first... while the
>client is still sending then the client will get error 10053
What would you expect to happen?
Well to be honest, I exptected:
1. The client to disconnect...
2. The client.socket.connected would become false.
3. The client.socket.sendbuf call would silently fail and return -1 or 0 :D
Then there is another weird thing... in case of errors I'd expect them
to be return via the OnError event...
But I am getting the impression this is a lower error generated by lower
winsock code or something...
At the moment I am not sure what happens... I have been playing games :D so as
soon as I am done with them and have some 'free' time I will look into this
:D... Maybe I will find out what happens or maybe there is nothing to find
out :D
I can imagine this to be a common problem...
1. The client is still sending when the server shutsdown.
or vice versa:
2. The server is still sending when the client shutsdown.
Is TCP able to gracefully shutdown under these circumstances ?
If so then there must be something wrong with the code/concept/algorithm ?
If not then one would need an extra protocol to gracefully shutdown.
Quote
>// client code:
>
>procedure TForm1.ClientSocket1Write(Sender: TObject;
>Socket: TCustomWinSocket);
>begin
>Memo1.Lines.Add('write');
>
>repeat
>
>ClientSize := 1400;
>
>// if socket is still connected then
>if Socket.Connected then
>begin
>
>ClientBytes := Socket.SendBuf( ClientData, ClientSize );
>// error 10053 ?!
>
>if ClientBytes>0 then
>begin
>ClientBytesSent := ClientBytesSent + ClientBytes;
>end;
>
>end;
>
>until (ClientBytes = -1) or (ClientBytes = 0) or (not
>Socket.Connected);
>end;
The Socket.Connected tests are probably redundant - whenever
Socket.Connected would return 'false', calling the send/recv functions
should also indicate an error. In other words, you're effectively checking
twice.
The idea was to first check if the connection is still open... if so then
it's safe to call sendbuf...
If the connection is closed... then no call to sendbuff should be made...
and so no error would be generated...
So it is kinda weird that an error is generated... that would mean this
connected property is not 'working' as planned.
Quote
If ClientSize is not zero, ClientBytes cannot be zero. There isn't a
special
meaning as there is for receiving data.
In short, for the sending side, your code two posts ago looked fine.
You asked in a previous post, "How long will [the send] loop run?" The
answer is that, with the socket set to non-blocking, it will run until the
send call would block (or you're done, or there's an error). The send call
must block if there is no space in the send buffer.
( Ok, the code is using non-blocking sockets. )
Quote
>// server code:
>
>procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
>Socket: TCustomWinSocket);
>begin
>Memo2.Lines.Add('client read');
>
>repeat
>
>// if socket is sill valid then
>if Socket.Connected then
>begin
>
>ServerSize := 1400;
>ServerBytes := Socket.ReceiveBuf( ServerData, ServerSize );
>
>if ServerBytes>0 then
>begin
>ServerBytesReceived := ServerBytesReceived + ServerBytes;
>end;
>
>end;
>
>until (ServerBytes = -1) or (ServerBytes = 0) or (not
>Socket.Connected);
>end;
Again, the Socket.Connected tests are probably redundant, and it's
probably
better without the loop (ie one read per OnRead event). In Winsock itself,
read events are "level" triggered, so if you don't read all the available
data, another event is generated.
You'll still need to check ServerBytes though, even without the loop. As I
implied above, 0 has a special meaning: the connection has been gracefully
closed.
I wonder if the client socket works that way too... I ll bet it probably
does... but for someone reason... the sendbuf
is still called... and generates an error... maybe it is an exception... :D
Later,
Skybuck.