Thread View: borland.public.cppbuilder.internet.socket
15 messages
15 total messages
Started by Josh Arnold
Thu, 14 Sep 2006 00:17
TClientSocket OnRead event issues
Author: Josh Arnold
Date: Thu, 14 Sep 2006 00:17
Date: Thu, 14 Sep 2006 00:17
25 lines
2013 bytes
2013 bytes
Hello, I have an application that acts as a client to a device running an embedded TCP/IP stack. The embedded device is the server and I'm trying to receive messages from the server. I'm using BDS 2006 but not using the socket components from the tool pallete, instead I am using the TClientSocket component. I open the socket and assign the OnRead event handler at run time. The server device properly receives any messages I send (I'm just sending text) and then replies back with the necessary data (again just text). I can see the response when capturing with Ethereal. But the OnRead event does not fire in my client app therefore my application never sees any of the responses from the server. Here is the bizarre part. I can run the Internet Chat example program from C++ Builder 5 on another machine and my app talks to it and receives from it just fine. AND I can use the Chat example program to talk to the embedded server device and it WILL see the responses from the server. Both applications use the same TClientSocket component. Any ideas anyone????? I am quite stumped thanks -Josh
Re: TClientSocket OnRead event issues
Author: Remy Lebeau (TeamB)
Date: Thu, 14 Sep 2006 00:32
Date: Thu, 14 Sep 2006 00:32
26 lines
2163 bytes
2163 bytes
"Josh Arnold" <jdaudio02@hotmail.com> wrote in message news:4508a026@newsgroups.borland.com... > I can see the response when capturing with Ethereal. But the OnRead > event does not fire in my client app therefore my application never > sees any of the responses from the server. Please show your actual code. The only way you would not be receiving the event is if the TClientSocket never received the notification in the first place. Since non-blocking sockets use the message queue, make sure that you are not using anything that can discard messages before they are processed. > I can run the Internet Chat example program from C++ Builder 5 on > another machine and my app talks to it and receives from it just fine. > AND I can use the Chat example program to talk to the embedded > server device and it WILL see the responses from the server. Both > applications use the same TClientSocket component. Then your failing application is not actually receiving any data from the embedded server to begin with, despite what Ethereal says. Ethereal sits at a very low level. Just because it says data is arriving at the TCP/IP layer does not necessary mean that the data is reaching the application layer. Gambit
Re: TClientSocket OnRead event issues
Author: Josh Arnold
Date: Thu, 14 Sep 2006 01:04
Date: Thu, 14 Sep 2006 01:04
44 lines
2632 bytes
2632 bytes
I will post code first thing tomorrow. > Then your failing application is not actually receiving any data from the > embedded server to begin with, despite what Ethereal says. Ethereal sits > at > a very low level. Just because it says data is arriving at the TCP/IP > layer > does not necessary mean that the data is reaching the application layer. I agree, but the old example chat program works using the same TClientSocket component and nearly identical code. Very strange! "Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message news:4508a3f3$2@newsgroups.borland.com... > > "Josh Arnold" <jdaudio02@hotmail.com> wrote in message > news:4508a026@newsgroups.borland.com... > >> I can see the response when capturing with Ethereal. But the OnRead >> event does not fire in my client app therefore my application never >> sees any of the responses from the server. > > Please show your actual code. The only way you would not be receiving the > event is if the TClientSocket never received the notification in the first > place. Since non-blocking sockets use the message queue, make sure that > you > are not using anything that can discard messages before they are > processed. > >> I can run the Internet Chat example program from C++ Builder 5 on >> another machine and my app talks to it and receives from it just fine. >> AND I can use the Chat example program to talk to the embedded >> server device and it WILL see the responses from the server. Both >> applications use the same TClientSocket component. > > > > Gambit > >
Re: TClientSocket OnRead event issues
Author: Remy Lebeau (TeamB)
Date: Thu, 14 Sep 2006 01:22
Date: Thu, 14 Sep 2006 01:22
17 lines
1597 bytes
1597 bytes
"Josh Arnold" <jdaudio02@hotmail.com> wrote in message news:4508aab1$1@newsgroups.borland.com... > I agree, but the old example chat program works using the > same TClientSocket component and nearly identical code. But, you are using it in two different IDE versions. You also did not indicate whether the embedded server is behind a router or firewall. It could be that the successful application is able to reach the server while the failing application is being blocked? It could also just be that your reading code is wrong and you are causing OnRead notification messages to be ignored. It is really hard to say right now without seeing your actual code. Gambit
Re: TClientSocket OnRead event issues
Author: Josh Arnold
Date: Thu, 14 Sep 2006 12:30
Date: Thu, 14 Sep 2006 12:30
72 lines
2931 bytes
2931 bytes
Gambit-
Here is my relevant code:
void Tfrm_Main::TCP_Init()
{
//client socket communicates with embedded server socket
client = new TClientSocket(frm_Main);
client->Address = "192.168.78.139";
client->Port = 1024;
client->ClientType = ctNonBlocking;
client->Open();
client->OnRead = myClientRead;
}
//Send message
void __fastcall Tfrm_Main::Button4Click(TObject *Sender)
{
client->Socket->SendText("hello\n");
}
//Event handler
void __fastcall Tfrm_Main::myClientRead(System::TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Text = Socket->ReceiveText();
//receiveFlag = true;
}
Its farily simple I call the TCP_Init() function on a button click. Then
send a message on Button4Click event.
The server is set up to immediately reply back to the failing client app,
and as mentioned before, the server is responding.
There is a router in between the two but no firewall. The Chat app works
with the server device from the same machine that fails on the client app.
Thanks for the quick help,
-Josh
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:4508b143@newsgroups.borland.com...
>
> "Josh Arnold" <jdaudio02@hotmail.com> wrote in message
> news:4508aab1$1@newsgroups.borland.com...
>
> > I agree, but the old example chat program works using the
> > same TClientSocket component and nearly identical code.
>
> But, you are using it in two different IDE versions. You also did not
> indicate whether the embedded server is behind a router or firewall. It
> could be that the successful application is able to reach the server while
> the failing application is being blocked? It could also just be that your
> reading code is wrong and you are causing OnRead notification messages to
be
> ignored. It is really hard to say right now without seeing your actual
> code.
>
>
> Gambit
>
>
Re: TClientSocket OnRead event issues
Author: Hans Galema
Date: Thu, 14 Sep 2006 13:31
Date: Thu, 14 Sep 2006 13:31
21 lines
1642 bytes
1642 bytes
Josh Arnold wrote: > client->Open(); > client->OnRead = myClientRead; Assign the eventhandler first: client->OnRead = myClientRead; client->Open(); What if you assign an onconnecthandler too? client->OnConnect = myClientConnect; client->OnRead = myClientRead; client->Open(); Does that trigger? You should wait for OnConnect before sending anything. HAns.
Re: TClientSocket OnRead event issues
Author: Josh Arnold
Date: Thu, 14 Sep 2006 14:56
Date: Thu, 14 Sep 2006 14:56
30 lines
1860 bytes
1860 bytes
Ok, I modified my code per Hans suggestion and still nothing. The OnConnect event is fired and I can get the RemoteAddress from the socket, but the responses from the server still do not trigger any OnRead events. "Hans Galema" <notused@notused.nl> wrote in message news:45095b16@newsgroups.borland.com... > Josh Arnold wrote: > > > client->Open(); > > client->OnRead = myClientRead; > > Assign the eventhandler first: > > client->OnRead = myClientRead; > client->Open(); > > What if you assign an onconnecthandler too? > > client->OnConnect = myClientConnect; > client->OnRead = myClientRead; > client->Open(); > > Does that trigger? > > You should wait for OnConnect before sending anything. > > HAns.
Re: TClientSocket OnRead event issues
Author: Remy Lebeau (TeamB)
Date: Thu, 14 Sep 2006 17:02
Date: Thu, 14 Sep 2006 17:02
21 lines
1808 bytes
1808 bytes
"Josh Arnold" <jarnold@atterotech.com> wrote in message
news:450949ba$1@newsgroups.borland.com...
Why are you waiting until after calling Open() to assign the event handler?
You should be doing it before instead:
client->OnRead = myClientRead;
client->Open();
> client->Socket->SendText("hello\n");
You are not checking the return value to make sure that the full text is
actually being sent. You are not taking into account that partial text can
be sent, requiring you to re-send the remaining data again. You are also
not taking into account that if a send operation blocks, the send will
report a failure, and you then have to wait until the OnWrite event is
triggered before you can send any further data.
Gambit
Re: TClientSocket OnRead event issues
Author: Josh Arnold
Date: Thu, 14 Sep 2006 17:26
Date: Thu, 14 Sep 2006 17:26
46 lines
2384 bytes
2384 bytes
Problem solved for now, It appears that the client socket needs a "garbage read" in order to get the OnRead event working. Since the OnConnect event fires I just stuck in a socket->RecieveText() and now the responses from the server are heard. Thanks for the help, don't know if this qualifies as a bug or not? -Josh "Josh Arnold" <jarnold@atterotech.com> wrote in message news:45096c00@newsgroups.borland.com... > Ok, I modified my code per Hans suggestion and still nothing. > > The OnConnect event is fired and I can get the RemoteAddress from the > socket, but the responses from the server still do not trigger any OnRead > events. > > > "Hans Galema" <notused@notused.nl> wrote in message > news:45095b16@newsgroups.borland.com... > > Josh Arnold wrote: > > > > > client->Open(); > > > client->OnRead = myClientRead; > > > > Assign the eventhandler first: > > > > client->OnRead = myClientRead; > > client->Open(); > > > > What if you assign an onconnecthandler too? > > > > client->OnConnect = myClientConnect; > > client->OnRead = myClientRead; > > client->Open(); > > > > Does that trigger? > > > > You should wait for OnConnect before sending anything. > > > > HAns. > >
Re: TClientSocket OnRead event issues
Author: Remy Lebeau (TeamB)
Date: Thu, 14 Sep 2006 17:30
Date: Thu, 14 Sep 2006 17:30
14 lines
1605 bytes
1605 bytes
"Josh Arnold" <jarnold@atterotech.com> wrote in message news:45098f13@newsgroups.borland.com... > It appears that the client socket needs a "garbage read" > in order to get the OnRead event working. No, it does not. Like I said earlier, non-blocking sockets use window messages as internal notifications. You do not need a dummy read in order to begin receiving those notifications. Something else has to be happening that is blocking them. Gambit
Re: TClientSocket OnRead event issues
Author: Josh Arnold
Date: Thu, 14 Sep 2006 21:50
Date: Thu, 14 Sep 2006 21:50
39 lines
2358 bytes
2358 bytes
Ok,
I still don't see what is blocking the initial read but it seems to be
working now.
My new problem is that I need to send a lot of small messages and get them
back ideally in the order that they were sent.
What would be the best approach to this problem?
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:45098bd2$1@newsgroups.borland.com...
>
> "Josh Arnold" <jarnold@atterotech.com> wrote in message
> news:450949ba$1@newsgroups.borland.com...
>
> Why are you waiting until after calling Open() to assign the event
handler?
> You should be doing it before instead:
>
> client->OnRead = myClientRead;
> client->Open();
>
> > client->Socket->SendText("hello\n");
>
> You are not checking the return value to make sure that the full text is
> actually being sent. You are not taking into account that partial text
can
> be sent, requiring you to re-send the remaining data again. You are also
> not taking into account that if a send operation blocks, the send will
> report a failure, and you then have to wait until the OnWrite event is
> triggered before you can send any further data.
>
>
> Gambit
>
>
Re: TClientSocket OnRead event issues
Author: Remy Lebeau (TeamB)
Date: Thu, 14 Sep 2006 22:03
Date: Thu, 14 Sep 2006 22:03
18 lines
1699 bytes
1699 bytes
"Josh Arnold" <jarnold@atterotech.com> wrote in message news:4509ccfc$1@newsgroups.borland.com... > My new problem is that I need to send a lot of small messages > and get them back ideally in the order that they were sent. TCP/IP guarantees that for you. All you have to is read whatever you receive. They will already be in the proper order. > What would be the best approach to this problem? Please go to http://www.deja.com and search through the newsgroup archives. Effectively usage of TClientSocket (especially in non-blocking mode) has been discussed many many times before, with full code examples. Gambit
Re: TClientSocket OnRead event issues
Author: Arnoud
Date: Mon, 25 Sep 2006 12:27
Date: Mon, 25 Sep 2006 12:27
40 lines
2380 bytes
2380 bytes
Hi, I made a similar program with BCB5 connecting to a embedded server running windows CE. The application has several TClientSocket components on the form. To communicate with the embedded device I make the TClientSocket connect and wait for the device to send its identification data before sending any data to it. Some of the established connections never trigger any OnRead event, making the BCB application believe that the device was successfully connected, but never responded with any data (no matter how many data the embedded device sends). In this situation sending data to the embedded device (using SendBuf) works Ok and the winCE application received the command. I started to log the TCP traffic and i noticed that the SYN/SYNACK/ACK handshake appeared to be normal, I could also see the incomming data from the embedded device. 1.) SYN packet app->device 2.) SYN ACK packet device->app 3.) ACK packet app->device 4.) DATA packet device->app I logged the following events of a connection that does not trigger any OnRead event: 1.) OnConnecting() 2.) OnRead() - returning 0 bytes 3.) OnConnect() 4.) Nothing.. Luckilly 95% of all connections work normally. I added a timeout, making the same TClientSocket component Close and then Connect to the same device. The retry works fine (mostly) I have little idea why it happens, anyone have an idea? Thank you, -Arnoud
Re: TClientSocket OnRead event issues
Author: Arnoud
Date: Tue, 26 Sep 2006 13:57
Date: Tue, 26 Sep 2006 13:57
28 lines
2199 bytes
2199 bytes
Josh Arnold schreef: > Problem solved for now, > > It appears that the client socket needs a "garbage read" in order to get the > OnRead event working. > Since the OnConnect event fires I just stuck in a > socket->RecieveText() and now the responses from the server are heard. > > Thanks for the help, don't know if this qualifies as a bug or not? > > -Josh Hi Josh, I got a similar problem in my communications with a embedded tcp/ip stack, i addded your 'garbage read' idea and it worked for me as well. OnRead() seems to trigger only *once*, and then expect our applications to do at least one Read operation to trigger again. Our applications probably did not expect to read data before OnConnect. The 'garbage read' probably reset the flag so OnRead() fired again. Did you use any other components inside your application? I have used a NMUDP(fastnet) component to handle someUDP traffic. Thank you for sharing the idea! -Arnoud
Re: TClientSocket OnRead event issues
Author: Remy Lebeau (TeamB)
Date: Tue, 26 Sep 2006 16:56
Date: Tue, 26 Sep 2006 16:56
58 lines
3830 bytes
3830 bytes
"Arnoud" <vult-r@endless-online.com> wrote in message
news:4519327b@newsgroups.borland.com...
> OnRead() seems to trigger only *once*, and then expect our
> applications to do at least one Read operation to trigger again.
That is how non-blocking sockets are designed to work. The socket only
sends one OnRead event to let you know that data is available, and then your
application has to read what is available before a new OnRead event can be
triggered again. This is explained in the socket API documentation:
(begin quote)
The Windows Sockets DLL will not continually flood an application with
messages for a particular network event. Having successfully posted
notification of a particular event to an application window, no further
message(s) for that network event will be posted to the application window
until the application makes the function call which implicitly re-enables
notification of that network event.
Event Re-enabling function
FD_READ recv, recvfrom, WSARecv, or WSARecvFrom
...
Any call to the re-enabling routine, even one which fails, results in
re-enabling of message posting for the relevant event.
For FD_READ, FD_OOB, and FD_ACCEPT events, message posting is
"level-triggered." This means that if the re-enabling routine is called and
the relevant condition is still met after the call, a WSAAsyncSelect message
is posted to the application. This allows an application to be event-driven
and not be concerned with the amount of data that arrives at any one time.
Consider the following sequence:
1. Network transport stack receives 100 bytes of data on socket s and
causes Windows Sockets 2 to post an FD_READ message.
2. The application issues recv(s, buffptr, 50, 0) to read 50 bytes.
3. Another FD_READ message is posted since there is still data to be
read.
With these semantics, an application need not read all available data in
response to an FD_READ message - a single recv in response to each FD_READ
message is appropriate. If an application issues multiple recv calls in
response to a single FD_READ, it can receive multiple FD_READ messages. Such
an application may need to disable FD_READ messages before starting the recv
calls by calling WSAAsyncSelect with the FD_READ event not set.
(end quote)
You DO NOT, however, need to do a "garbage" read to get the OnRead event to
trigger in the first place. If you connect to a server and do not do any
reads at all, you will still get an OnRead event when the server sends data.
I have been using TClientSocket for years and never had any problems with
that.
Gambit
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