Board index » delphi » High frequency TServerSocket / TClientSocket connection problem

High frequency TServerSocket / TClientSocket connection problem

<matthias.faulst...@t-online.de> skrev i melding
news:3a9be130.12956260@news.btx.dtag.de...

Quote
> Hello!

> I have a problem with tcp-ip data transfer.

> I'm using a none-blocking connection between two Delphi applications,
> one with a TServerSocket, one with a TClientSocket, very similar to
> Delphi's chat-exaple.

Non-blocking connections are a bit risky if you're about to send 5000 packets
a sec., I'd think. When sending intensively, you should possibly rely on a
thread rather than dumping it all in the nic buffer (or whereever the packet
queue will be buffered).

Quote
> Unlike the example, I have to transmit small packages (100 Bit
> maximum) with a high frequency, up to 5000 per second. A 10MBits
> Ethernet connection should handle this traffic without problems.

I wouldn't be too sure about this, remember the overhead of packet headers &
returned acknowledge...your max. throughput of a TCP/IP LAN connection would
be some 600kbytes / sec. This means, your packages must not result in more
than 120b's each. Maybe you won't get more packets/sec through at 120
b/packet than at 1500 b/packet ? (Don't know about this for sure, but you
have the ethernet frame level, too, you know)...

Quote
> I am running counters on both applications to see, how many packages
> become sent and how many arrive and see, that most of the packages are
> going lost (without error messages on the OnClientError event of the
> TClientSocket or the OnError event of the TServerSocket.)

Try with blocking sockets. Then you easily measure the number of packets sent
per sec....

--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorgeremovet...@itte.no (remove the obvious)

 

Re:High frequency TServerSocket / TClientSocket connection problem


On Tue, 27 Feb 2001 22:29:07 +0100, "Bj?rge S?ther"

Quote
<REMOVE_bsaether@THIS_online.no> wrote:
>Non-blocking connections are a bit risky if you're about to send 5000 packets
>a sec., I'd think. When sending intensively, you should possibly rely on a
>thread rather than dumping it all in the nic buffer (or whereever the packet
>queue will be buffered).

All examples demonstrating blocking socket connections I saw were
synchronously. This means, that in the execute - procedure of a
TServerClientThread first a read and then a write function was
performed. Unlike this I need an asynchronously connection, because
the server as well as the client may send packages independently from
a directly response or a or a previously request of the other side.

Is it possible to use two independent threads, one for sending and one
for receiving for the TClientSocket and for each client socket which
becomes created on the server-side?

Matthias Faulstich

Re:High frequency TServerSocket / TClientSocket connection problem


<matthias.faulst...@t-online.de> skrev i melding
news:3a9c965d.447984@news.btx.dtag.de...

Quote
> On Tue, 27 Feb 2001 22:29:07 +0100, "Bj?rge S?ther"
> <REMOVE_bsaether@THIS_online.no> wrote:

> >Non-blocking connections are a bit risky if you're about to send 5000
packets
> >a sec., I'd think. When sending intensively, you should possibly rely on a
> >thread rather than dumping it all in the nic buffer (or whereever the
packet
> >queue will be buffered).

> All examples demonstrating blocking socket connections I saw were
> synchronously. This means, that in the execute - procedure of a
> TServerClientThread first a read and then a write function was
> performed. Unlike this I need an asynchronously connection, because
> the server as well as the client may send packages independently from
> a directly response or a or a previously request of the other side.

> Is it possible to use two independent threads, one for sending and one
> for receiving for the TClientSocket and for each client socket which
> becomes created on the server-side?

Yes. But Send() could often be performed directly, as long as it's a small
amount of data and no receiving is done within the same routine. Send()
rarely blocks...
One technique is using a mailbox, and let the working thread wait on the
"other side" until something is posted (send operations). Reversely, having a
receive thread posting received packets into a mailbox, and a worker thread
doing the processing on the other side of the mailbox.
--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorgeremovet...@itte.no (remove the obvious)

Re:High frequency TServerSocket / TClientSocket connection problem


On Wed, 28 Feb 2001 23:08:59 +0100, "Bj?rge S?ther"

Quote
<REMOVE_bsaether@THIS_online.no> wrote:
>Yes. But Send() could often be performed directly, as long as it's a small
>amount of data and no receiving is done within the same routine. Send()
>rarely blocks...

Isn't it so that in a blocking connection a Send() must wait until a
Read() on the other side is ready to receive data?
In my none-blocking connection I saw, that while a Send() has been
performed 9 times, only one or two OnRead events on the other side
occured (on a connection over the loopback address 127.0.0.1). It
would be very helpful, if a blocking connection would prevent such
data loss.

Quote
>One technique is using a mailbox, and let the working thread wait on the
>"other side" until something is posted (send operations). Reversely, having a
>receive thread posting received packets into a mailbox, and a worker thread
>doing the processing on the other side of the mailbox.

I know mailboxes from a RTOS (RTKernel from OnTime) but I havn't heard
about mailboxes in Delphi. Do you know any mailbox-class(es) in
Delphi?

Matthias Faulstich

Re:High frequency TServerSocket / TClientSocket connection problem


<matthias.faulst...@t-online.de> skrev i melding
news:3a9e8ba0.909848@news.btx.dtag.de...

Quote
> On Wed, 28 Feb 2001 23:08:59 +0100, "Bj?rge S?ther"
> <REMOVE_bsaether@THIS_online.no> wrote:

> >Yes. But Send() could often be performed directly, as long as it's a small
> >amount of data and no receiving is done within the same routine. Send()
> >rarely blocks...

> Isn't it so that in a blocking connection a Send() must wait until a
> Read() on the other side is ready to receive data?

No, it's only blocking in Send() while the nic is busy. Receive operation is
blocking until a packet arrives that meets the socket specifications.

Quote
> In my none-blocking connection I saw, that while a Send() has been
> performed 9 times, only one or two OnRead events on the other side
> occured (on a connection over the loopback address 127.0.0.1). It
> would be very helpful, if a blocking connection would prevent such
> data loss.

If you know you're going to send many packets, your would probably need some
kind of acknowledge to be sent from the other side. But, this is exactly what
connection-oriented sockets are meant for, so you don't need to reinvent this
sort of wheel. Unless you're interacting with an allready established
communications protocol...

Quote
> >One technique is using a mailbox, and let the working thread wait on the
> >"other side" until something is posted (send operations). Reversely,
having a
> >receive thread posting received packets into a mailbox, and a worker
thread
> >doing the processing on the other side of the mailbox.

> I know mailboxes from a RTOS (RTKernel from OnTime) but I havn't heard
> about mailboxes in Delphi. Do you know any mailbox-class(es) in
> Delphi?

That's strange, I learned about them from the RTKernel, too. My task was
creating a WinSock client that could talk to an RTKernel IPX DOS-application.
I created a mailbox class for Delphi in this project, and I could e-mail it
to you if you're interested. This code isn't as generic as it should, partly
because at that time (D2) there was no OOP Winsock wrappers available like
TClient-/TServerSocket, and it communicated with this kinda strange RTKernel
way of IPX'ing. And - I was a novice with both Delphi and Network
programming.

--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorgeremovet...@itte.no (remove the obvious)

Re:High frequency TServerSocket / TClientSocket connection problem


Quote
>If you know you're going to send many packets, your would probably need some
>kind of acknowledge to be sent from the other side. But, this is exactly what
>connection-oriented sockets are meant for, so you don't need to reinvent this
>sort of wheel. Unless you're interacting with an allready established
>communications protocol...

Does the last remark mean, that it is necessary to close the
connection after each transmission and to open it again before the
next to prevent the need of a software handshake?

Quote

>That's strange, I learned about them from the RTKernel, too. My task was
>creating a WinSock client that could talk to an RTKernel IPX DOS-application.
>I created a mailbox class for Delphi in this project, and I could e-mail it
>to you if you're interested. This code isn't as generic as it should, partly
>because at that time (D2) there was no OOP Winsock wrappers available like
>TClient-/TServerSocket, and it communicated with this kinda strange RTKernel
>way of IPX'ing. And - I was a novice with both Delphi and Network
>programming.

I already made a kind of fifo-class, so it would be easy to implement
a TSimpleEvent object to block its read function until data are
available. This construction would have a behaviour very similar to a
mailbox.

Matthias Faulstich

Re:High frequency TServerSocket / TClientSocket connection problem


<matthias.faulst...@t-online.de> skrev i melding
news:3a9fa234.3767317@news.btx.dtag.de...

Quote
> >If you know you're going to send many packets, your would probably need
some
> >kind of acknowledge to be sent from the other side. But, this is exactly
what
> >connection-oriented sockets are meant for, so you don't need to reinvent
this
> >sort of wheel. Unless you're interacting with an allready established
> >communications protocol...

> Does the last remark mean, that it is necessary to close the
> connection after each transmission and to open it again before the
> next to prevent the need of a software handshake?

The word "Connection" is essential here; A Connection-oreiented socket is
duplex mode communication, you send and receive acknowledge. TCP (and SPX
???) uses this scheme, while UDP is simplex.
No, you don't need to close a connectionless socket, you'd just use another
socket for receiving acknowledge. Remember, the RTKernel solution didn't
establish a "socket" connected to a specific port, every packet dropped in at
the same point and was redirected by means of a sender ID or similar (an
object pointer ???). Acknowledge was an "automatic" feature implemented at
RTKernel level.

Quote
> >That's strange, I learned about them from the RTKernel, too. My task was
> >creating a WinSock client that could talk to an RTKernel IPX
DOS-application.
> >I created a mailbox class for Delphi in this project, and I could e-mail
it
> >to you if you're interested. This code isn't as generic as it should,
partly
> >because at that time (D2) there was no OOP Winsock wrappers available like
> >TClient-/TServerSocket, and it communicated with this kinda strange
RTKernel
> >way of IPX'ing. And - I was a novice with both Delphi and Network
> >programming.

> I already made a kind of fifo-class, so it would be easy to implement
> a TSimpleEvent object to block its read function until data are
> available. This construction would have a behaviour very similar to a
> mailbox.

Exactly.

--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorgeremovet...@itte.no (remove the obvious)

Re:High frequency TServerSocket / TClientSocket connection problem


Quote
>The word "Connection" is essential here; A Connection-oreiented socket is
>duplex mode communication, you send and receive acknowledge. TCP (and SPX
>???) uses this scheme, while UDP is simplex.
>No, you don't need to close a connectionless socket, you'd just use another
>socket for receiving acknowledge. Remember, the RTKernel solution didn't
>establish a "socket" connected to a specific port, every packet dropped in at
>the same point and was redirected by means of a sender ID or similar (an
>object pointer ???). Acknowledge was an "automatic" feature implemented at
>RTKernel level.

Hmm...
My application consists of a RTKernel program (using the additional
available RTIP library) running on an industrial PC which controls a
machine on one and a Delphi program running on a desktop PC to provide
an user interface on the other side.
Unfortunately I haven't the RTIP documentation here and can't check
this before Monday, but I think to remember that I read, RTIP can
establish a TCP-IP socket connection. The library functions to do this
(if I remember correct) needs an IP address and a port number.
Or am I confused about "socket connection" and other kinds of possible
TCP-IP connections?
My idea is to use the TServerSocket component in the Delphi
application and create a matching client with RTIP / RTKernel.

But there is something I am still confused about. You told me former:

Quote
>>>If you know you're going to send many packets, your would probably
>>> need some kind of acknowledge to be sent from the other side.
>>> But, this is exactly what connection-oriented sockets are meant
>>> for, so you don't need to reinvent this

If TCP-IP sockets have already implemented the acknowledgement -
functionality, and TServerSocket / TClientSocket both establish TCP-IP
socket connections, what is the reason for the data loss when both
components are used and a count of Send() functions are performed one
after each other? I tried just 9 Send() which resulted in 2
OnClientRead.

Matthias Faulstich

Re:High frequency TServerSocket / TClientSocket connection problem


<matthias.faulst...@t-online.de> skrev i melding
news:3a9fe2b3.3364578@news.btx.dtag.de...

Quote
> >The word "Connection" is essential here; A Connection-oreiented socket is
> >duplex mode communication, you send and receive acknowledge. TCP (and SPX
> >???) uses this scheme, while UDP is simplex.
> >No, you don't need to close a connectionless socket, you'd just use
another
> >socket for receiving acknowledge. Remember, the RTKernel solution didn't
> >establish a "socket" connected to a specific port, every packet dropped in
at
> >the same point and was redirected by means of a sender ID or similar (an
> >object pointer ???). Acknowledge was an "automatic" feature implemented at
> >RTKernel level.

> Hmm...
> My application consists of a RTKernel program (using the additional
> available RTIP library) running on an industrial PC which controls a
> machine on one and a Delphi program running on a desktop PC to provide
> an user interface on the other side.
> Unfortunately I haven't the RTIP documentation here and can't check
> this before Monday, but I think to remember that I read, RTIP can
> establish a TCP-IP socket connection. The library functions to do this
> (if I remember correct) needs an IP address and a port number.
> Or am I confused about "socket connection" and other kinds of possible
> TCP-IP connections?
> My idea is to use the TServerSocket component in the Delphi
> application and create a matching client with RTIP / RTKernel.

I forgot something you wrote earlier, that you were on TCP/IP. When you
mentioned RTKernel, I was back on SPX/IPX, the only protocols supported by
the RTKernel installation I was working with.

Quote
> But there is something I am still confused about. You told me former:

> >>>If you know you're going to send many packets, your would probably
> >>> need some kind of acknowledge to be sent from the other side.
> >>> But, this is exactly what connection-oriented sockets are meant
> >>> for, so you don't need to reinvent this

> If TCP-IP sockets have already implemented the acknowledgement -
> functionality, and TServerSocket / TClientSocket both establish TCP-IP
> socket connections, what is the reason for the data loss when both
> components are used and a count of Send() functions are performed one
> after each other? I tried just 9 Send() which resulted in 2
> OnClientRead.

There is a socket option, TCP_NODELAY, that may be set if one sends a large
number of small packets. Chek it out (described under 'setsockopt' in WinAPI
help).

You're using SendBuf, are you ??? Checking on any result values ?

--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorgeremovet...@itte.no (remove the obvious)

Re:High frequency TServerSocket / TClientSocket connection problem


Quote

>There is a socket option, TCP_NODELAY, that may be set if one sends a large
>number of small packets. Chek it out (described under 'setsockopt' in WinAPI
>help).

Do you have an example to set TCP_NODELAY for a TServer- /
TClientSocket - connection?

Quote
>You're using SendBuf, are you ??? Checking on any result values ?

A few days ago, yes, but since you recommeded me to use a blocking
connection with own transmission handshake, I use a solution with
TWinSocketStream.Write.

I create a kind of "checksum" by XOR all bytes of a datagram and
decide upon this, whether or not a received "package" is valid. (Ok,
Ok, very low level and not very tricky)

Matthias Faulstich

Re:High frequency TServerSocket / TClientSocket connection problem


"Matthias Faulstich" <matthias.faulst...@t-online.de> skrev i melding
news:3aa13e8d.6948000@news.btx.dtag.de...

Quote

> >There is a socket option, TCP_NODELAY, that may be set if one sends a
large
> >number of small packets. Chek it out (described under 'setsockopt' in
WinAPI
> >help).

> Do you have an example to set TCP_NODELAY for a TServer- /
> TClientSocket - connection?

No, I'm sorry, I never tried it. But the code is straightforward:

  setsockopt(Socket.SocketHandle, IPPROTO_TCP, TCP_NODELAY, 1, 4);

Quote
> >You're using SendBuf, are you ??? Checking on any result values ?

> A few days ago, yes, but since you recommeded me to use a blocking
> connection with own transmission handshake, I use a solution with
> TWinSocketStream.Write.
> I create a kind of "checksum" by XOR all bytes of a datagram and
> decide upon this, whether or not a received "package" is valid. (Ok,
> Ok, very low level and not very tricky)

Are you checking on result values ? Any errors ???

--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorgeremovet...@itte.no (remove the obvious)

Re:High frequency TServerSocket / TClientSocket connection problem


On Sun, 4 Mar 2001 21:09:37 +0100, "Bj?rge S?ther"

Quote
<REMOVE_bsaether@THIS_online.no> wrote:
>> Do you have an example to set TCP_NODELAY for a TServer- /
>> TClientSocket - connection?

>No, I'm sorry, I never tried it. But the code is straightforward:

>  setsockopt(Socket.SocketHandle, IPPROTO_TCP, TCP_NODELAY, 1, 4);

Hey! Thats exactly what I needed, because mainly I didn't know where
to get the SOCKET parameter from.

Quote

>Are you checking on result values ? Any errors ???

Actually I create a number of classes to encapsulate the complete
functionallity:
a serverlistening to one port (read / write handshake)
a client writing to this port (write / wait for handshake)
the same for the reverse procedure on an other port
and all that buffered with mailboxes and combined with threads which
read the mailboxes and handle the data stream to and from the sockets.
The interface for the main application will be a "Send" (buffer)
procedure and an OnData (received)- property for both, the server and
the client.

I hope tomorrow it will be grown so far that I can make a test to see,
how many datagrams per second are possible and how many errors occure.

Quote

>--
>Bjoerge Saether
>Consultant / Developer
>http://www.itte.no
>Asker, Norway
>bjorgeremovet...@itte.no (remove the obvious)

Re:High frequency TServerSocket / TClientSocket connection problem


"Matthias Faulstich" <matthias.faulst...@t-online.de> skrev i melding
news:3aa3c31e.26597044@news.btx.dtag.de...

Quote
> On Sun, 4 Mar 2001 21:09:37 +0100, "Bj?rge S?ther"
> <REMOVE_bsaether@THIS_online.no> wrote:

> >> Do you have an example to set TCP_NODELAY for a TServer- /
> >> TClientSocket - connection?

> >No, I'm sorry, I never tried it. But the code is straightforward:

> >  setsockopt(Socket.SocketHandle, IPPROTO_TCP, TCP_NODELAY, 1, 4);

> Hey! Thats exactly what I needed, because mainly I didn't know where
> to get the SOCKET parameter from.

> >Are you checking on result values ? Any errors ???

> Actually I create a number of classes to encapsulate the complete
> functionallity:
> a serverlistening to one port (read / write handshake)
> a client writing to this port (write / wait for handshake)
> the same for the reverse procedure on an other port
> and all that buffered with mailboxes and combined with threads which
> read the mailboxes and handle the data stream to and from the sockets.
> The interface for the main application will be a "Send" (buffer)
> procedure and an OnData (received)- property for both, the server and
> the client.

> I hope tomorrow it will be grown so far that I can make a test to see,
> how many datagrams per second are possible and how many errors occure.

I just *have* to make a guess: 900/sec (if size is somewhat 500b).
;-)

Good luck !

--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorgeremovet...@itte.no (remove the obvious)

Re:High frequency TServerSocket / TClientSocket connection problem


On Mon, 5 Mar 2001 20:44:01 +0100, "Bj?rge S?ther"

Quote
<REMOVE_bsaether@THIS_online.no> wrote:

>I just *have* to make a guess: 900/sec (if size is somewhat 500b).
>;-)

>Good luck !

Unfortunately not enough luck to solve all problems today.  But
tomorrow... ;-)

Ive got a problem with my client connections. If a client connects to
the server, the TServerSocket fires a count of events. I use
OnClientConnect to create a Thread to handle the client connection.
But if a client disconnects, then happenes --- nothing. And so if the
client connects again, a new thread becomes created for the same
application. I "investigated", that the first thread becomes aware of
his lost connection first, if he tries to make a write. But in my
"read - and -write handshake" part is no need to write until the
client sends data.

Do you know how to become aware of a lost client without writing to
the "dead" connection?

Matthias Faulstich

Other Threads