Board index » delphi » Random bindings when using Reuse Socket in TIdTCPServer

Random bindings when using Reuse Socket in TIdTCPServer


2003-07-26 02:09:50 PM
delphi25
I run multiple instances of an application containing a TIdTCPServer
component - this is done for performance and redundancy reasons as the
server maintains long-lived connections to its clients. I am able to bind
multiple applications to the port by setting the Reuse Socket property to
rsTrue.
This all works well except that the instance of the server that accepts new
connections is unpredictable. Sometimes, the last server to bind to the
port accepts new connections (this is the desired behaviour) but at other
times all new connections will get accepted by the first server to bind to
the port and will only get accepted by others if the original server unbinds
from the port.
I cannot establish any pattern to this. Does anyone know what logic is
applied in these circumstances as it seems to be random to me?
Thanks,
Ian.
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (www.grisoft.com).
Version: 6.0.502 / Virus Database: 300 - Release Date: 18/07/2003
 
 

Re:Random bindings when using Reuse Socket in TIdTCPServer

Did I understand you right ?
You have multilpe EXE / DLL file executed in parallel on the same system :
- everyone has TIdTCPServer
- every TIdTCPServer binds to the very same TCP port on the same Network
interface to listen
Wow - I'd expect that this behaves strange :
Only 1 app can bind to the same port on the same network interface at any
given time on ALL OS I got to know so far...
If you want to achieve redundancy and performance then run your app once per
system - the redundancy comes by using multiple systems !
You can achieve this too ( with less security as with multiple systems ! )
by using mutiple NICs and bind every instance of your app to a specific
unique NIC...
If you use multiple systems and you don't want to make the client choose
which IP it has to connect to you can use DNS with multiple IP adresses for
the same name - in this case DNS implements some sort of round robin which
is a very basic means of load balancing...
Yahia
"Ian Davies" <XXXX@XXXXX.COM>schrieb im Newsbeitrag
Quote
I run multiple instances of an application containing a TIdTCPServer
component - this is done for performance and redundancy reasons as the
server maintains long-lived connections to its clients. I am able to bind
multiple applications to the port by setting the Reuse Socket property to
rsTrue.

This all works well except that the instance of the server that accepts
new
connections is unpredictable. Sometimes, the last server to bind to the
port accepts new connections (this is the desired behaviour) but at other
times all new connections will get accepted by the first server to bind to
the port and will only get accepted by others if the original server
unbinds
from the port.

I cannot establish any pattern to this. Does anyone know what logic is
applied in these circumstances as it seems to be random to me?

Thanks,

Ian.



---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (www.grisoft.com).
Version: 6.0.502 / Virus Database: 300 - Release Date: 18/07/2003


 

Re:Random bindings when using Reuse Socket in TIdTCPServer

Thanks for the response. Yes, I am running multiple instances of an
application all bound to the same port. I don't believe this is unusual.
Apache does much the same thing on Windows - multiple processes all
listening on port 80. SO_REUSE_ADDR was intended for this, I understand.
One of the primary goals is to separate the listener from the main
application logic which I have achieved. I am currently toying with having
multiple listeners per application logic which will help the system scale
through the use of a one-to-many relationship.
I really wanted to know how the system decides which listener services
incoming requests. Can anyone please provide any help?
Thanks in advance.
Ian.
"Yahia El-Qasem" <XXXX@XXXXX.COM>writes
Quote
Did I understand you right ?

You have multilpe EXE / DLL file executed in parallel on the same system :

- everyone has TIdTCPServer
- every TIdTCPServer binds to the very same TCP port on the same Network
interface to listen

Wow - I'd expect that this behaves strange :

Only 1 app can bind to the same port on the same network interface at any
given time on ALL OS I got to know so far...

If you want to achieve redundancy and performance then run your app once
per
system - the redundancy comes by using multiple systems !
You can achieve this too ( with less security as with multiple systems ! )
by using mutiple NICs and bind every instance of your app to a specific
unique NIC...

If you use multiple systems and you don't want to make the client choose
which IP it has to connect to you can use DNS with multiple IP adresses
for
the same name - in this case DNS implements some sort of round robin which
is a very basic means of load balancing...

Yahia

"Ian Davies" <XXXX@XXXXX.COM>schrieb im Newsbeitrag
news:3f221b56$XXXX@XXXXX.COM...
>I run multiple instances of an application containing a TIdTCPServer
>component - this is done for performance and redundancy reasons as the
>server maintains long-lived connections to its clients. I am able to
bind
>multiple applications to the port by setting the Reuse Socket property
to
>rsTrue.
>
>This all works well except that the instance of the server that accepts
new
>connections is unpredictable. Sometimes, the last server to bind to the
>port accepts new connections (this is the desired behaviour) but at
other
>times all new connections will get accepted by the first server to bind
to
>the port and will only get accepted by others if the original server
unbinds
>from the port.
>
>I cannot establish any pattern to this. Does anyone know what logic is
>applied in these circumstances as it seems to be random to me?
>
>Thanks,
>
>Ian.
>
>
>
>---
>Outgoing mail is certified Virus Free.
>Checked by AVG anti-virus system (www.grisoft.com).
>Version: 6.0.502 / Virus Database: 300 - Release Date: 18/07/2003
>
>


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (www.grisoft.com).
Version: 6.0.504 / Virus Database: 302 - Release Date: 24/07/2003
 

Re:Random bindings when using Reuse Socket in TIdTCPServer

AFAIK your interpretation is wrong - take a look at these links :
support.microsoft.com/default.aspx
msdn.microsoft.com/library/en-us/winsock/winsock/using_so_exclusiveaddruse.asp
www.experts-exchange.com/CXO/Networking/Q_20412583.html
https://www.cs.ucr.edu/pipermail/cs164/2002-May/000267.html
www.unixguide.net/network/socketfaq/4.5.shtml
All these say that it could only work under very specific circumstances (
there are even NG articles saying that the implementation of SO_REUSEADDR
i.e. on Windows NT is buggy ) etc.
Your app scales very good if you have it multithreaded and even more if you
have several multithreaded worker applications which do the work on behalf
of your listener process.
I don't see a need to even have multiple listeners on the same port...
For example Oracle Enterprise DB does NOT have more than one listener
process bound to the same interface + port combination - even with>1000
users connected to it...
Hope this makes my last answer a bit more clear...
Yahia
"Ian Davies" <XXXX@XXXXX.COM>schrieb im Newsbeitrag
Quote
Thanks for the response. Yes, I am running multiple instances of an
application all bound to the same port. I don't believe this is unusual.
Apache does much the same thing on Windows - multiple processes all
listening on port 80. SO_REUSE_ADDR was intended for this, I understand.

One of the primary goals is to separate the listener from the main
application logic which I have achieved. I am currently toying with
having
multiple listeners per application logic which will help the system scale
through the use of a one-to-many relationship.

I really wanted to know how the system decides which listener services
incoming requests. Can anyone please provide any help?

Thanks in advance.

Ian.


"Yahia El-Qasem" <XXXX@XXXXX.COM>writes
news:XXXX@XXXXX.COM...
>Did I understand you right ?
>
>You have multilpe EXE / DLL file executed in parallel on the same system
:
>
>- everyone has TIdTCPServer
>- every TIdTCPServer binds to the very same TCP port on the same Network
>interface to listen
>
>Wow - I'd expect that this behaves strange :
>
>Only 1 app can bind to the same port on the same network interface at
any
>given time on ALL OS I got to know so far...
>
>If you want to achieve redundancy and performance then run your app once
per
>system - the redundancy comes by using multiple systems !
>You can achieve this too ( with less security as with multiple systems
! )
>by using mutiple NICs and bind every instance of your app to a specific
>unique NIC...
>
>If you use multiple systems and you don't want to make the client choose
>which IP it has to connect to you can use DNS with multiple IP adresses
for
>the same name - in this case DNS implements some sort of round robin
which
>is a very basic means of load balancing...
>
>Yahia
>
>"Ian Davies" <XXXX@XXXXX.COM>schrieb im Newsbeitrag
>news:3f221b56$XXXX@XXXXX.COM...
>>I run multiple instances of an application containing a TIdTCPServer
>>component - this is done for performance and redundancy reasons as the
>>server maintains long-lived connections to its clients. I am able to
bind
>>multiple applications to the port by setting the Reuse Socket property
to
>>rsTrue.
>>
>>This all works well except that the instance of the server that
accepts
>new
>>connections is unpredictable. Sometimes, the last server to bind to
the
>>port accepts new connections (this is the desired behaviour) but at
other
>>times all new connections will get accepted by the first server to
bind
to
>>the port and will only get accepted by others if the original server
>unbinds
>>from the port.
>>
>>I cannot establish any pattern to this. Does anyone know what logic
is
>>applied in these circumstances as it seems to be random to me?
>>
>>Thanks,
>>
>>Ian.
>>
>>
>>
>>---
>>Outgoing mail is certified Virus Free.
>>Checked by AVG anti-virus system (www.grisoft.com).
>>Version: 6.0.502 / Virus Database: 300 - Release Date: 18/07/2003
>>
>>
>
>


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (www.grisoft.com).
Version: 6.0.504 / Virus Database: 302 - Release Date: 24/07/2003


 

Re:Random bindings when using Reuse Socket in TIdTCPServer

Always happy to help...
If I understand you correctly you are worried about security aspects - in
this case several thing could / should be done :
1. DMZ ( Demilitarized Zone )
Put your server with two NICs into a DMZ so that you have a shapr
distinction between internal and external network connections. Setup both
firewalls that even if someone hacks your server your internal network won't
be in danger...
2. Binding
Bind server processes only to necessary ports and shutdown any unneeded
services.
Implement your protocol in a way that clients need to authanticate against
your server before issuing requests.
Some sort of encryption ( from fast to very strong, even think about PKE )
would help to prevent misuse of your server...
For extreme security consider using a very different approach :
A Store and Forward approach even works without any direct connections
between clients and servers. You would need setup some sort of Messaging
based solution ( like MQ Series from IBM ) and let your clients store their
request through the MQ Series Server.
These servers just queue the requests and responses. You write handlers
which can run on as many internal servers you. The handler polls the queue
and does whatever it has to. When it is finished with the work it queues up
the response into the server...
The client just polls the response queue and takes the response out there...
This way the server accessible to the clients has very limited capabilities
and if it gets compromised it would do direct harm to any real ( =
processing ) server.
I don't know enough about the nature of your protocol. If you have something
like connect - request - long processing time - response - disconnect than
you could just use shared memory as IPC mechanism and have one or more apps
take out the pending requests from there and give the response back....
If you have between connect and disconnect multiple request/work/response
happening the same could still be used...
Perhaps the following approach is better suited if your processing needs
long time to finish :
- Every client get at first connect a "session id" ( this could be created
to be even some sort of security means )
- Every client announces at which port it will listen for responses
- Every clients sets up a listener thread on that port
Communication between your server and the clients occurs with UDP for the
sending of requests...
Responses are actively sent from the server to the client ( to the listening
port ) which could be TCP or UDP...
This way a lot more clients could be active than TCP would allow ( TCP has a
maximum of 65000 ports... ) without having any impact on your server except
the processing load...
The processing load could even be disributed internally to many processing
servers using some other IPC mechanism ( which could include communicating
via TCP or UDP on an internal NIC ).
HTH
Yahia
"Ian Davies" <XXXX@XXXXX.COM>schrieb im Newsbeitrag
Quote
Hello Yahia,

Many thanks for the links and comments. This has really convinved me that
what I am trying to achieve is probably a bad thing.

I still need to isolate the server from the clients so that errant clients
do not kill the server. For this, I will still implement the listener as
a
separate process that communicates with the server using pipes or a
connectionless protocol of some kind. I don't believe threads will
provide
sufficient insulation from hack attempts or crashed clients but I am now
convinved that there should only be one listener for each server thereby
avoiding any issues surrounding reusing sockets.

Incidentally, do you know of any resources that describe how something
like
Oracle handles its clients. My application is much closer to a database
server than a web server as the connections are long-lived rather than the
request-response of HTTP.

Thanks again.

Ian.

 

Re:Random bindings when using Reuse Socket in TIdTCPServer

Hello Yahia,
My server maintains connections to many clients and pushes textual data as a
custom protocol to those clients as and when changes occur, in real time.
It is not necessarilly a connect-request-long
processing-response-disconnect, more of a connect-request-response as and
when it is relevant-disconnect. UDP is not practical in my specific
circumstances as the data must arrive and must be in the correct order - TCP
is ideal. Because I am only dealing with a few hundred or so clients, I
think that message queue middleware would be overkill. If I need to support
many more clients then this would probably be the better approach. I did
look at IBM MQ which is very good but very expensive and administratively
inensive so I am implementing the infrastructure myself at the moment.
My specific concerns are that becuase this application is on the internet
the connections to the clients may be unreliable or break. I am not so
worried about being hacked but am more concerned with the server suffering
from misbehaving clients. For example, clients could lock up or they could
flood the server and cause it to crash. Because I am implementing the
listener as a separate process, the only part that would crash is the
listener - which can be spawned again very easily. The processing system,
which maintains state and connections to my non-internet aware legacy
systems, will be unaffected. I was hoping to have multiple listeners per
processing system so that if one of them crashes then not all of the clients
would be affected. The load is not sufficient to necessarilly warrant one
server per listener which is why I wanted to have them all on one server
sharing the same port which means I'd still get the redundancy if one of
them failed (the clients connected to the others would be unaffected, as
would the processing part of the server). I think that I should stick with
one listener per processing system while my load remains constant at the
current level and if I need to scale, I will place the listeners on other
servers.
Do you have any pointers on the Oracle listener architecture, by any chance?
Thanks again for your help.
Ian.
"Yahia El-Qasem" <XXXX@XXXXX.COM>writes
Quote
Always happy to help...

If I understand you correctly you are worried about security aspects - in
this case several thing could / should be done :

1. DMZ ( Demilitarized Zone )
Put your server with two NICs into a DMZ so that you have a shapr
distinction between internal and external network connections. Setup both
firewalls that even if someone hacks your server your internal network
won't
be in danger...

2. Binding
Bind server processes only to necessary ports and shutdown any
unneeded
services.


Implement your protocol in a way that clients need to authanticate against
your server before issuing requests.
Some sort of encryption ( from fast to very strong, even think about PKE )
would help to prevent misuse of your server...


For extreme security consider using a very different approach :

A Store and Forward approach even works without any direct connections
between clients and servers. You would need setup some sort of Messaging
based solution ( like MQ Series from IBM ) and let your clients store
their
request through the MQ Series Server.
These servers just queue the requests and responses. You write handlers
which can run on as many internal servers you. The handler polls the queue
and does whatever it has to. When it is finished with the work it queues
up
the response into the server...
The client just polls the response queue and takes the response out
there...

This way the server accessible to the clients has very limited
capabilities
and if it gets compromised it would do direct harm to any real ( =
processing ) server.


I don't know enough about the nature of your protocol. If you have
something
like connect - request - long processing time - response - disconnect than
you could just use shared memory as IPC mechanism and have one or more
apps
take out the pending requests from there and give the response back....

If you have between connect and disconnect multiple request/work/response
happening the same could still be used...

Perhaps the following approach is better suited if your processing needs
long time to finish :

- Every client get at first connect a "session id" ( this could be created
to be even some sort of security means )
- Every client announces at which port it will listen for responses
- Every clients sets up a listener thread on that port

Communication between your server and the clients occurs with UDP for the
sending of requests...
Responses are actively sent from the server to the client ( to the
listening
port ) which could be TCP or UDP...

This way a lot more clients could be active than TCP would allow ( TCP has
a
maximum of 65000 ports... ) without having any impact on your server
except
the processing load...
The processing load could even be disributed internally to many processing
servers using some other IPC mechanism ( which could include communicating
via TCP or UDP on an internal NIC ).


HTH

Yahia

"Ian Davies" <XXXX@XXXXX.COM>schrieb im Newsbeitrag
news:XXXX@XXXXX.COM...
>Hello Yahia,
>
>Many thanks for the links and comments. This has really convinved me
that
>what I am trying to achieve is probably a bad thing.
>
>I still need to isolate the server from the clients so that errant
clients
>do not kill the server. For this, I will still implement the listener
as
a
>separate process that communicates with the server using pipes or a
>connectionless protocol of some kind. I don't believe threads will
provide
>sufficient insulation from hack attempts or crashed clients but I am now
>convinved that there should only be one listener for each server thereby
>avoiding any issues surrounding reusing sockets.
>
>Incidentally, do you know of any resources that describe how something
like
>Oracle handles its clients. My application is much closer to a database
>server than a web server as the connections are long-lived rather than
the
>request-response of HTTP.
>
>Thanks again.
>
>Ian.
>


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (www.grisoft.com).
Version: 6.0.504 / Virus Database: 302 - Release Date: 24/07/2003
 

Re:Random bindings when using Reuse Socket in TIdTCPServer

"Martin James" <XXXX@XXXXX.COM>writes news:<XXXX@XXXXX.COM>...
Quote
"Ian Davies" <XXXX@XXXXX.COM>writes
news:3f23734b$XXXX@XXXXX.COM...

..
Quote
Why are you so worried about the listener? The listener thread only accept
new connections & hands the sockets off to peer threads for the rest of the
connect time - that is all it does. Once the connection is up, the listener
thread plays no part in client<>server communications. Simplified
pseudocode for the listener in my servers:
I apologise but I used the word listener in error. I mean the client handling system as opposed to the server's logic. Problems due to unreliable connections, failed clients, etc are quite common for me and do affect the server and therefore I need to ensure that the server does not suffer because of this. The server process maintains state and links to the legacy systems so this needs to be preserved at all costs so, for this reason, I am implementing all remote client handling stuff in a separate process to isolate the server.
Your suggestion of a protocol level application ping sounds appropriate here and I think that I will implement this.
In my application, the IdTCPServer pushes data to the clients as and when it changes. My problem is, what happens when the client locks up and the IdTCPServer's send buffer fills-up? Will Indy react gracefully and disconnect the client or will it lock the thread waiting for more buffer space to become available? If the latter case, will my calls from the main thread to write to the socket in the stagnant thread also then block?
Thanks for the response and tips.
Ian.