Passing an open TCP socket to another application
-
Thank you. That looks very useful, at least in the case of handing off the socket to an already-open application. What would be the preferred method of handing off a socket to an application which isn't yet launched (assuming .net 2.0)? I've not used named pipes, since the managed API's for those FWIU only appeared in .net 3.5, though if they're easy to use from .net that might be handy. Otherwise I could have the newly-launched application "telnet" into the service port, say "hey I'm here, this is my process ID, and I'd like a socket if you have one"; the service could then give the socket to the new application. One of my design goals is to minimize the possibility of the service imposing an excessive burden on the system even if things go wrong (e.g. a connection comes in and the service launches the application, but the application never gets around to dealing with the port). I don't particularly like the idea of the service having to hold the connection until the application gets around to asking for it, but it wouldn't be too horrible. I could probably have a 30-second timeout or something on it (if the application hasn't picked up the socket by then, the remote device that's "telnet"ing in will likely give up anyway), but that adds some complexity. BTW, what's the best style for using the Select function? Creating three lists from scratch each time I want to poll for data, and then using a dictionary to map the connections in each list back to my own connection-info objects seems rather klunky.
For interprocess communication between processes on that same machine, I'd just use .NET remoting. The IpcChannel/IpcServerChannel/IpcClientChannel classes are efficient, and probably use named pipes for their transport.
supercat9 wrote:
what's the best style for using the Select function?
I don't know - I never use it, and I personally think it's kind of dated. I much prefer I/O completion ports or the asynchronous APIs in .NET. Thread pool stuff is much more efficient. I prefer a class that represents/wraps a connection (e.g. a socket) and handles its own asynchronous I/O.
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
For interprocess communication between processes on that same machine, I'd just use .NET remoting. The IpcChannel/IpcServerChannel/IpcClientChannel classes are efficient, and probably use named pipes for their transport.
supercat9 wrote:
what's the best style for using the Select function?
I don't know - I never use it, and I personally think it's kind of dated. I much prefer I/O completion ports or the asynchronous APIs in .NET. Thread pool stuff is much more efficient. I prefer a class that represents/wraps a connection (e.g. a socket) and handles its own asynchronous I/O.
Mark Salsbery Microsoft MVP - Visual C++ :java:
Mark Salsbery wrote:
I prefer a class that represents/wraps a connection (e.g. a socket) and handles its own asynchronous I/O.
I never really got a grasp of how to asynchronous I/O with operations that may need to time out or be aborted; I've read that there isn't really good support for that. I think the concern by the socket implementors was that if an application times out or otherwise decides to abort an operation with a TCP socket, there's no guarantee as to what data may or may not be 'in transit'. Certainly such an issue is reasonable, but in some cases it may be easier and cheaper to recover from the 'unknown data' scenario than to close and reopen the socket. For example, if the remote system includes an 'echo' command, the PC can ask the remote machine to echo back a GUID, repeating the request until the proper GUID is echoed(*). Once the proper echo is received, the PC will know that the only thing that could possibly be in the transmit pipe would be more copies of the 'echo' command, and the only thing that could possibly be in the receive pipe would be more copies of the echoed GUID. (*) If both endpoints were running TCP natively, there would be no point in retransmitting the data. On the other hand, many embedded systems use a TCP-to-serial gateway, and there is a possibility of data loss on the serial link. What would be the best way to set up an application if it has to be able to exchange data via the following three methods, interchangeably: -1- TCP socket -2- Serial port -3- Thread which polls a custom USB device each millisecond to see if there's any data Are there any good example programs showing how best to do such things?
-
Thank you. That looks very useful, at least in the case of handing off the socket to an already-open application. What would be the preferred method of handing off a socket to an application which isn't yet launched (assuming .net 2.0)? I've not used named pipes, since the managed API's for those FWIU only appeared in .net 3.5, though if they're easy to use from .net that might be handy. Otherwise I could have the newly-launched application "telnet" into the service port, say "hey I'm here, this is my process ID, and I'd like a socket if you have one"; the service could then give the socket to the new application. One of my design goals is to minimize the possibility of the service imposing an excessive burden on the system even if things go wrong (e.g. a connection comes in and the service launches the application, but the application never gets around to dealing with the port). I don't particularly like the idea of the service having to hold the connection until the application gets around to asking for it, but it wouldn't be too horrible. I could probably have a 30-second timeout or something on it (if the application hasn't picked up the socket by then, the remote device that's "telnet"ing in will likely give up anyway), but that adds some complexity. BTW, what's the best style for using the Select function? Creating three lists from scratch each time I want to poll for data, and then using a dictionary to map the connections in each list back to my own connection-info objects seems rather klunky.
supercat9 wrote:
What would be the preferred method of handing off a socket to an application which isn't yet launched
I would prefer not to do that. So I would want to have zero other choices before adopting that approach. Keep it simple by just having the new process start a new connection and design session and application protocol for aligning the data that is transmitted. Passing sockets across applications just sounds like a bad idea. Of course I don't have your complete requirements, I'm just saying I would think that is a last resort.
-
Mark Salsbery wrote:
I prefer a class that represents/wraps a connection (e.g. a socket) and handles its own asynchronous I/O.
I never really got a grasp of how to asynchronous I/O with operations that may need to time out or be aborted; I've read that there isn't really good support for that. I think the concern by the socket implementors was that if an application times out or otherwise decides to abort an operation with a TCP socket, there's no guarantee as to what data may or may not be 'in transit'. Certainly such an issue is reasonable, but in some cases it may be easier and cheaper to recover from the 'unknown data' scenario than to close and reopen the socket. For example, if the remote system includes an 'echo' command, the PC can ask the remote machine to echo back a GUID, repeating the request until the proper GUID is echoed(*). Once the proper echo is received, the PC will know that the only thing that could possibly be in the transmit pipe would be more copies of the 'echo' command, and the only thing that could possibly be in the receive pipe would be more copies of the echoed GUID. (*) If both endpoints were running TCP natively, there would be no point in retransmitting the data. On the other hand, many embedded systems use a TCP-to-serial gateway, and there is a possibility of data loss on the serial link. What would be the best way to set up an application if it has to be able to exchange data via the following three methods, interchangeably: -1- TCP socket -2- Serial port -3- Thread which polls a custom USB device each millisecond to see if there's any data Are there any good example programs showing how best to do such things?
supercat9 wrote:
asynchronous I/O with operations that may need to time out or be aborted; I've read that there isn't really good support for that. I think the concern by the socket implementors was that if an application times out or otherwise decides to abort an operation with a TCP socket, there's no guarantee as to what data may or may not be 'in transit'.
Is it really an issue in practice with TCP? If you implement a timeout or abort you run the risk of data loss regardless - there's no way for an endpoint to know what the other endpoint is about to do.
supercat9 wrote:
What would be the best way to set up an application if it has to be able to exchange data via the following three methods, interchangeably
I don't know, beyond making a base common interface then implementing three derived implementations that implement the interface for the given communication type.
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
supercat9 wrote:
What would be the preferred method of handing off a socket to an application which isn't yet launched
I would prefer not to do that. So I would want to have zero other choices before adopting that approach. Keep it simple by just having the new process start a new connection and design session and application protocol for aligning the data that is transmitted. Passing sockets across applications just sounds like a bad idea. Of course I don't have your complete requirements, I'm just saying I would think that is a last resort.
I agree. And using TCP and sockets, the session IS the connected socket so it's not very complex to implement.
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
supercat9 wrote:
What would be the preferred method of handing off a socket to an application which isn't yet launched
I would prefer not to do that. So I would want to have zero other choices before adopting that approach. Keep it simple by just having the new process start a new connection and design session and application protocol for aligning the data that is transmitted. Passing sockets across applications just sounds like a bad idea. Of course I don't have your complete requirements, I'm just saying I would think that is a last resort.
I have a reserved TCP port for a class of applications which generally involve an electronic device (not a PC) connecting to a server. The first line of data sent from a device will identify the device type and serial number. Different devices will need to be handled by different applications. It is necessary to keep the remote end as simple as possible, since it's a relatively unsophisticated microcontroller. While it might be possible to build a mega-application which would handle everything internally (indeed, that's what I have now) splitting things off into different applications should improve system reliability and extensibility.
-
supercat9 wrote:
asynchronous I/O with operations that may need to time out or be aborted; I've read that there isn't really good support for that. I think the concern by the socket implementors was that if an application times out or otherwise decides to abort an operation with a TCP socket, there's no guarantee as to what data may or may not be 'in transit'.
Is it really an issue in practice with TCP? If you implement a timeout or abort you run the risk of data loss regardless - there's no way for an endpoint to know what the other endpoint is about to do.
supercat9 wrote:
What would be the best way to set up an application if it has to be able to exchange data via the following three methods, interchangeably
I don't know, beyond making a base common interface then implementing three derived implementations that implement the interface for the given communication type.
Mark Salsbery Microsoft MVP - Visual C++ :java:
Mark Salsbery wrote:
Is it really an issue in practice with TCP? If you implement a timeout or abort you run the risk of data loss regardless - there's no way for an endpoint to know what the other endpoint is about to do.
Is there any practical way to abort an asynchronous TCP operation without closing a connection, if one is willing to accept the loss or late arrival of data prior to the abort, but one wants to avoid memory or resource leaks, weird crashes, etc.? I know that in many of the applications for which TCP is designed, dropping a connection would be preferable to losing data while keeping a connection, but when dealing with embedded systems that isn't always true. Also, btw, is it safe to have one thread write to a socket while a different thread reads it? I know that having two threads writing or two threads reading would likely be problematical at best, but the write/read case would seem common enough I would hope the implementors would have handled it correctly.
-
Mark Salsbery wrote:
Is it really an issue in practice with TCP? If you implement a timeout or abort you run the risk of data loss regardless - there's no way for an endpoint to know what the other endpoint is about to do.
Is there any practical way to abort an asynchronous TCP operation without closing a connection, if one is willing to accept the loss or late arrival of data prior to the abort, but one wants to avoid memory or resource leaks, weird crashes, etc.? I know that in many of the applications for which TCP is designed, dropping a connection would be preferable to losing data while keeping a connection, but when dealing with embedded systems that isn't always true. Also, btw, is it safe to have one thread write to a socket while a different thread reads it? I know that having two threads writing or two threads reading would likely be problematical at best, but the write/read case would seem common enough I would hope the implementors would have handled it correctly.
supercat9 wrote:
is it safe to have one thread write to a socket while a different thread reads it?
I've never seen it documented, and may never, but it works on Windows and I rely on it working :)
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
I have a reserved TCP port for a class of applications which generally involve an electronic device (not a PC) connecting to a server. The first line of data sent from a device will identify the device type and serial number. Different devices will need to be handled by different applications. It is necessary to keep the remote end as simple as possible, since it's a relatively unsophisticated microcontroller. While it might be possible to build a mega-application which would handle everything internally (indeed, that's what I have now) splitting things off into different applications should improve system reliability and extensibility.
-
supercat9 wrote:
is it safe to have one thread write to a socket while a different thread reads it?
I've never seen it documented, and may never, but it works on Windows and I rely on it working :)
Mark Salsbery Microsoft MVP - Visual C++ :java:
Thanks for your help. I think I have a workable approach for the handoff (at least my simple test apps work fine). As for aborting an asynchronous operation, I've decided the best approach is probably to have the asynchronous receive handler call a delegate for the incoming data. That way, if I give up on receiving one type of data and want to start looking for another type, I don't need to abort the pending receive--I can simply leave it pending; when data comes in, it will go to the new delegate.