Thread View: borland.public.cppbuilder.internet.socket
3 messages
3 total messages
Started by Carlos Moreno
Mon, 21 Apr 2008 15:54
Trouble with TcpClient component
Author: Carlos Moreno
Date: Mon, 21 Apr 2008 15:54
Date: Mon, 21 Apr 2008 15:54
81 lines
4158 bytes
4158 bytes
Hi, I'm having major trouble and major frustration when trying to migrate an application from C++ Builder 6 to Builder 2007 (I have the trial version, so it may not be the latest release 2). The short story / bottom line: how can I emulate the non- blocking functionality of TClientSocket, where I transmit whenever I need to transmit, and get an event whenever the socket received data from the server? The long / detailed story: My existing application uses sockets (TClientSocket) in non-blocking mode for *fully asynchronous* communications. TClientSocket is not supported in C++B2007, and the closest thing seems to be TcpClient (which also exists in C++B6, so this could help with the transition). With TClientSocket, I set it in non-blocking mode, and I do socket->Open() when the user activates the connection. Works like a charm: whenever the user transmits something, I receive an OnReceive (or was it OnRead?) event, to which I respond by calling socket->ReceiveBuf and read the received data. I pretty much ignore the OnSend event, as that one simply tells me that I *can* transmit --- I simply transmit when the user triggers an action that requires transmitting. Ok, I'm trying to emulate exactly the above --- the docs in C++B6 for this class/component are utterly useless; and so are C++B2007's --- The entry TcpClient takes me to the documentation for TIdTcpClient --- Indy's tcp client socket, which does not look even remotely similar to TcpClient. The little it says suggests that it works exactly the same; however, they don't. When I call socket->Open(), I immediately receive an error (an OnError event, with error code WOULDBLOCK --- meaning that the call to connect returned immediately but the operation has not been completed.... Well DUH! It's in non-blocking mode !!! How could it be completed? And how why would it tell the application that there was an error? (needless to say that with TClientSocket, I get no error, and instead, I get an OnConnect event a fraction of a second after calling socket->Open() .... Seems like the obviously correct thing to do) The connection *does* succeed, but I never get an OnConnected event (I know it succeeds for two reasons: 1) if I call socket->Open() again, I get an error ALREADYCONNECTED; and 2) if I now call socket->ReceiveBuf, I do read the server's greeting message --- the server transmits immediately upon the connection being accepted) The thing is, I never get an OnReceive event (well, I do, but I do get it in response to my call to ReceiveBuf --- clearly, I need it to be the other way around; I would only call ReceveiBuf when I'm notified, via an event, that the socket just received data); I really really need this feature, since my application has other things to do and can not afford to do polling on the socket to see if there is data, nor set it in blocking mode. Sure, I could make a separate thread and do polling or use the socket in blocking mode, but that would be a major restructuring of the application, so I'd *really* like to stay away from that option. Any tips on what's going on or how to make this work? Am I doing something wrong? Is the functionality of these sockets hopelessly broken? (in which case, suggestions?) Thanks! Carlos --
Re: Trouble with TcpClient component
Author: Remy Lebeau (TeamB)
Date: Mon, 21 Apr 2008 16:36
Date: Mon, 21 Apr 2008 16:36
67 lines
3866 bytes
3866 bytes
"Carlos Moreno" <moreno_h3gd@mochima.com> wrote in message news:480cb8b5$1@newsgroups.borland.com... > The short story / bottom line: how can I emulate the non- > blocking functionality of TClientSocket, where I transmit > whenever I need to transmit, and get an event whenever the > socket received data from the server? TClientSocket is deprecated, but it is still available in BCB 2007 (install the dclsockets100.bpl packet), and works the same as it did before. > TClientSocket is not supported in C++B2007 Yes, it is. IT is simply not installed by default anymore. > and the closest thing seems to be TcpClient TTcpClient is nowhere even close to TClientSocket. They are very different. TTcpClient was created at a time when Borland was trying to write its own cross-platform socket classes. Those classes were not implemented very well, though, and lack a LOT of functionality. I strongly recommend not using them at all. Stick with TClientSocket instead, or else use a third-party sockt library instead, such as Indy, ICS, or Synapse. > I pretty much ignore the OnSend event That is a mistake, especially since you were using a non-blocking socket. If you trying to pass too much data to TClientSocket at one time, SendBuf/Text() fails with a return code of -1 and WSAGetLastError() returns WSAEWOULDBLOCK. In that situation, you need to wait for the OnSend event to fire before you can pass any further data to the socket - including re-sending the data that triggered the blockage in the first place! A lot of TClientSocket (and TServerSocket) users ignore that fact when they shouldn't be. > as that one simply tells me that I *can* transmit --- I simply transmit > when the user triggers an action that requires transmitting. But that is still not a guarantee that the socket will be able to accept everything you tell it to transmit. If it doesn't, and if you do not handle it properly, then you will corrupt your communications with the other party. > The little it says suggests that it works exactly the same; TTcpClient does not work like TClientSocket, not even close. > The thing is, I never get an OnReceive event TTcpClient DOES NOT have asynchronous events at all!!! > well, I do, but I do get it in response to my call to ReceiveBuf Which is exactly how TTcpClient is coded to work. You will NOT get the OnReceive event asynchronously! You have to continuously invoke your own reading operations, and then TTcpClient will read whatever is available at the time. > clearly, I need it to be the other way around; I would only > call ReceveiBuf when I'm notified, via an event, that the > socket just received data) There are no asynchronous notifications in TTcpClient. Which is one of the reasons why I hate that component and never advise anyone to use it. Gambit
Re: Trouble with TcpClient component
Author: Carlos Moreno
Date: Mon, 21 Apr 2008 16:55
Date: Mon, 21 Apr 2008 16:55
55 lines
2689 bytes
2689 bytes
Hi Remy!
>TClientSocket is deprecated, but it is still available in BCB 2007 (install
>the dclsockets100.bpl packet), and works the same as it did before.
OH!! That's actually good news, I guess... (I'm somewhat
having a flashback of having been told this long ago --- C++
Builder 2006, perhaps? ... But I think at the time I did not
have much reasons to want to migrate, so a default that did
not directly support my existing application felt enough to
decide not to migrate... It is also conveivable that I'm
just having a random deja-vu when reading your comment above)
>> and the closest thing seems to be TcpClient
>
>TTcpClient is nowhere even close to TClientSocket.
From your description, I now completely agree with you...
The thing is, it does have about the same properties, the
same events, and the little docs available give descriptions
that suggest that the functionality is indeed the same.
For instance, this is BC++B6's description of OnReceive for
TTcpClient:
"Occurs after a socket receives data, but before it passes the
data to the application
[ ... ]
Description
Write an OnReceive event handler to read from the socket
connection ..."
I don't know, maybe I'm misinterpreting the above, but it did
sound a lot like a description of how TClientSocket works! :-(
> I strongly recommend not using them at all.
You definitely sold your case, no argument there!
>> I pretty much ignore the OnSend event
>
>That is a mistake [ ... ]
Well, I was simplifying a bit my post --- I do handle the
possibility of overflowing the local buffer when transmitting.
But good to hear the additional comments about the issue.
Thanks again! Your message was extremely helpful!!
Carlos
--
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads