in reply to Why won't this socket client terminate?

I don't know for sure that you are writing both ends but it sounds like that is a possibility (otherwise there would have been an interface spec for the thing that you are talking to).

1). I guess the first question is whether this is a multi-request server or not? Apparently the answer to that is: yes. It is presumably leaving the socket open for you to send additional lines to it. A single request server would have "hung up" on you when the output was finished and your while loop would have terminated.

2). The next question is whether a result can contain multiple lines or not? If not, then you send one line via print and get one line back like: $x=<$socket>;. If the server can return multiple lines, then it has to be worked out how the client will know that all the lines have been received. One common scheme would be that the last line contains just a period '.' followed by \n. Other schemes are possible, instead of say the character '.', it could be a CTL-A or whatever you want, even a string like "END-OF-TRANSMISSION". You use a while loop to receive the incoming lines, perhaps like: while (defined($line=<$socket>) and $line !~ /^\.$/){...}

3). The third thing to figure out is how to "hang up" from the client end. The server typically has a timer running and will "hang up" if it hasn't heard from the client for X amount of time. But to free resources more efficiently, there would be some kind of "quit" command or "quit packet". What this line would look like is up to you or was up to the server author. It can be anything that cannot be confused with a normal server request. Normally you would send this before your client exits. When the server gets this, it knows that you (the client) are going away and the server closes the socket at its end. The server doesn't get otherwise notified that you closed the socket. To be "polite" you should tell it that you are doing so, rather than rely upon it to figure this out at some later point in time.

There are of course other considerations like signals, but these are error handling situations instead of the main line "good machine" case.

Oh, your line: $| = 1;, doesn't do anything in your program. That statement only applies to the currently selected file handle (what print goes to by default), which in this case is stdout. I would call the autoflush() method on the $socket if you need to do this, but apparently this is not needed here.

Replies are listed 'Best First'.
Re^2: Why won't this socket client terminate?
by cormanaz (Deacon) on Jul 10, 2011 at 15:12 UTC
    Actually, no someone else wrote the server. Supposedly sending a blank line will terminate the parser, which is why I terminated the call with \n\n. I will have to dig into the server code and figure out what's going on now that I know I haven't don't anything wrong on the client. And duh, yes I should use autoflush!
      Ok, sorry for being long winded. Your code looks fine although sounds like autoflush() should be used. When the server closes the socket, it will look like an EOF at your end.

      Some ideas to try that might help some not so good code at the server end: -try putting the "\n" in a separate print statement to make sure it gets sent as the first char in a packet. -try " \n" a space before \n in case this guy's regex is wrong. Other than that, I can't think of anything else you could do.

      Update: Another idea occurred to me. If you change: print "$_"; to print "****$_****"; You might see some invisible white space character in what is being returned to you (maybe the server is sending a blank line to you..and has botched the close($socket) code at their end? This is just odd because you are so very close - getting connected and a legible response back is usually way more than half the battle!

        Just to follow up...The problem was, indeed, on the server side. It was not closing the client connection.