Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

tcp port open?

 [1/15] from: koopmans:itr:ing:nl at: 9-Oct-2001 9:20


Hi, Is there a way to now if a tcp port is open on both sides. So that a server (or client) can see whether or not the other side of the pipe is still open? Thanks, Maarten

 [2/15] from: petr:krenzelok:trz:cz at: 9-Oct-2001 10:22


Maarten Koopmans wrote:
> Hi, > > Is there a way to now if a tcp port is open on both sides. So that a server > (or client) can see whether or not the other side of the pipe is still open?
I am not sure. Designing our camera we looked at Ethereal (http://www.ethereal.org) packet monitor, and TCP communication is several stages process of various ACK, SYN, RST, PSH, FIN type packets. There is no real connection on the network, just packets sent here and there. That is why someone can watch your packets (sniff) and see what you are sending, if connected to the same network. So, alive connection is just some state in your tcp stack on your side, irrelevant to other side of "connection". There is also known case of semi-connection - e.g. one side timeouts, and the other side is still able to send packets, which are really delivered, just not probably processed. So, theoretically, if opposite side sends you FIN or RST assigned packet, you should note it. This question is, however, for Holger. We have 'query function available, maybe Rebol somehow knows, if opposite side closed the connection? -pekr-

 [3/15] from: philip:hayes:btcellnet at: 9-Oct-2001 9:53


You should have receive a notification that the connection has dropped that's the nature of TCP!

 [4/15] from: koopmans:itr:ing:nl at: 9-Oct-2001 11:00


I know.... but I can't see that in Rebol. I am thinking of adding 'persistent connections' to Rugby but I need to know if the pipe is broken in order to do that. --Maarten On Tuesday 09 October 2001 10:53, you wrote:

 [5/15] from: petr:krenzelok:trz:cz at: 9-Oct-2001 11:05


Hayes Philip wrote:
> You should have receive a notification that the connection has dropped > that's the nature of TCP!
Yes, such notification (FIN or RST type packets) is delivered, but to your OS tcp/ip stack layer. It is not clear however, that Rebol exposes such info anywhere into the port structure or to be caught by 'querry function ... but, of course, I can be wrong :-) -pekr-

 [6/15] from: philip:hayes:btcellnet at: 9-Oct-2001 10:21


This is how my tcp-server deals with it wait-ports: none listen-port: open/no-wait/direct/binary tcp://:9999 wait-ports: [ listen-port ] forever [ ; Perform asynch wait !!! wait wait-ports ; Is port descriptor set ? if not ( none? ( wait [ 0 listen-port ] ) ) [ ; Add port to block append wait-ports first listen-port ] ; Set scope of port checking check-ports: next wait-ports ; Check port activity ? while [ ( length? check-ports ) > 0 ] [ conn: first check-ports ; Is port still active ? either query conn [ ; Port active ... so check if any data to be read either not ( none? ( wait [ 0 conn ] ) ) [ ; Yes .. so determine size of data to be read readbuffer: copy #{} readbuffer: copy conn ; If length is none? then connection has been closed either none? readbuffer [ ; Close down port and tidy up wait-ports block entry close conn remove check-ports ] [ ; Is this NOT a HTTP request ? either none? ( find readbuffer HTTP/1. ) [ ; Remove data from port clear conn ; Move onto next port check-ports: next check-ports ] [ ; HTTP request so detrmine what to do ... ; Remember it's a non-persistent connection ; Tidy up clear conn close conn ] ; VIP - empty out buffer area !!! clear readbuffer ] ; end of either none? readbuffer ] [ check-ports: next check-ports ] ] [ ; Port is no longer active ! ; tidy up clear conn close conn remove check-ports ] ; end of query conn ] ; end of while ( length? ... ] quit

 [7/15] from: petr::krenzelok::trz::cz at: 9-Oct-2001 11:33


Maarten Koopmans wrote:
> I know.... but I can't see that in Rebol. > > I am thinking of adding 'persistent connections' to Rugby but I need to know > if the pipe is broken in order to do that.
error? try [insert port stuff] ? That's what Holger suggested me for my FastCGI problems ... -pekr-

 [8/15] from: koopmans:itr:ing:nl at: 9-Oct-2001 12:52


Phil, You are correct about the none? with copy Thanks, Maarten

 [9/15] from: koopmans:itr:ing:nl at: 9-Oct-2001 12:48


copy returns none when there is no data query returns always true on an opened port regardless of the other side. So... question remains open. --Maarten

 [10/15] from: philip:hayes:btcellnet at: 9-Oct-2001 12:12


In addition you could place a timeout on the wait wait wait-ports 600 ..and then loop through the port block performing the checks

 [11/15] from: sqlab:gmx at: 9-Oct-2001 13:18


> Hi, > Is there a way to now if a tcp port is open on both sides. So that a
<<quoted lines omitted: 3>>
> Thanks, > Maarten
Hello Marten You can either try a read before any sending in order to see, if the connection is still valid, or if you do a wait on your port-list, you should get the closing. Of course, an error? try [sending some data] prevents you from failing, if the connection is closed during the transmission. AR AR

 [12/15] from: koopmans:itr:ing:nl at: 9-Oct-2001 13:22


This post was actually send before my thanks, you're right post. You are right about copy and none --Maarten

 [13/15] from: koopmans:itr:ing:nl at: 9-Oct-2001 13:34


This you shouldn't do when doing a reasonable high-performance server. I noticed that non-blocking waits eat up CPU. --Maarten

 [14/15] from: g:santilli:tiscalinet:it at: 10-Oct-2001 15:06


Maarten Koopmans wrote:
> Is there a way to now if a tcp port is open on both sides. So that a server > (or client) can see whether or not the other side of the pipe is still open?
As long as the TCP stack has received the close packet, you can. If you open the port as /no-wait, using COPY will return (AFAIK): - a non-empty string, i.e. the data; - an empty string, meaning the connection is open but there's no data available in the buffers; - NONE, meaning the port has been closed on the other side. HTH, Gabriele. -- Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/

 [15/15] from: holger:rebol at: 18-Oct-2001 10:35


On Tue, Oct 09, 2001 at 12:48:49PM +0200, Maarten Koopmans wrote:
> copy returns none when there is no data > query returns always true on an opened port regardless of the other side. > > So... question remains open.
It is a little complicated, unfortunately. The problem is that TCP is full-duplex, but within the TCP protocol both directions are logically separated, i.e. a TCP connection really consists of two half-duplex pipes, each going in one direction. Both pipes are always created at the same time, when the connection is opened, but it is possible to close only one of them and keep the other one open, leading to a "half-closed" connection. At the TCP protocol level one side can only close its send pipe, not its receive pipe. The connection is completely closed once both sides have closed their send pipes. It is possible for a TCP connection to stay in a half-closed state for an arbitrary amount of time. This is not an error condition. It is not very common, but some protocols do make use of it. It is not possible to close only the receive pipe of a connection. (The shutdown() function call in C allows that, but for TCP it is basically a no-op, i.e. the other side is never informed about it, so even in C closing the receive pipe has no real effect.) What this means is that with TCP there is no way to tell the other side that you are no longer willing to accept data. *Usually* when one side recognizes that the peer has closed its send pipe, the other side closes its send pipe as well, resulting in a completely closed connection. This is not always the case though. For instance with many of the trivial query protocols (daytime, auth etc.) it is common for the client to send its request and immediately close its send pipe. Then it waits on its receive pipe for the server's response. The server only closes its send pipe after sending its response, even if its receive pipe has been closed by the peer before it gets a chance to respond. In order to allow this functionality it is imperative that a server does not automatically close its send pipe once its receive pipe has been closed by the peer. Otherwise it would be unable to respond to requests via a half-closed connection. What this means for REBOL is: You can detect whether your receive pipe has been closed by the peer by performing a 'copy on the port, assuming the port is in /no-wait mode. A none return means the other side has closed its send pipe (your receive pipe), any other value means that your receive pipe is still open. A query on a port only tells you whether a port is connected at all, not which pipes of the connection have which state. If the other side closes its send pipe then you are still connected (because your send pipe is still open), so query still returns true, and you can still send data. Of course if the other side actually accepts that data is a different matter. That depends on whether the other side only closed its send pipe or whether it completely closed the socket. There is no way for the local host to detect that, because that information is not transmitted through TCP. One exception though: Some, arguably broken, TCP/IP stacks (e.g. Windows) return errors (RST) to the peer when they receive data for a socket that has been closed by the program after the program exits. Most other stacks simply acknowledge the data and throw it away. For you that means when writing data to a TCP port, and the receiver is "no longer there" then one of two things may happen: either your data is silently accepted and ignored, or you may get an error. Which one it is does not depend on your TCP/IP stack, but on the peer's TCP/IP stack and how it handles program termination. Checking whether your incoming side has been closed is NOT the right way to determine whether the peer is "still there", because you may get "false positives" on half-closed connections, as explained above. (Unless, of course, you know that the protocol you are running across the TCP channel is never supposed to use half-closed connections. In that case that kind of check is safe.) At the moment REBOL does not allow you to close only one pipe of a connection. We plan to add that in one of the next versions, through get/set-modes. -- Holger Kruse [holger--rebol--com]

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted