Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Win32 sockets and disconnects

by HaB (Sexton)
on Dec 13, 2000 at 01:33 UTC ( [id://46331]=perlquestion: print w/replies, xml ) Need Help??

HaB has asked for the wisdom of the Perl Monks concerning the following question:

Hello all...

I have a little situation here I thought some of you might be able to shed some light on. I have a socket server/client combo running. The server I wrote myself, but the client is someone else's. (That may be important, I dunno). Here is the basic problem:

Both are designed to be run in the field, using the Internet as a method of connecting, so in order to simulate various problems, we have been fooling around with a couple of ways to disrupt the connection to see if the server will detect that, and cycle itself. (Which is what it's designed to do).

For the first test, we start a batch send on the client, let it begin, and yank the network cable.

Everything's fine. The server discards the incomplete message (if any), and cycles itself. Plugging the cable back in has the desired effect of the client continuing where it left off. All fine and dandy.

For the second test, we start the batch send, and Ctrl-C the client program. The server again registers the disconnect, and cycles itself. The problem starts when we then restart the client. The client comes up and says it makes a successful connection, and begins sending data again. The server, however, never registers a connect at all. It just sits listening. Since the client waits for an ACK message from the server between each message it sends, it gets stuck waiting for an ACK on a message that according to the server, never got there in the first place. The server never sends a NACK because it never even registers the connection attempt.

I am really unfamiliar with sockets under win32 anyway, and it's been a while since programming them on *nix.

Any thoughts? Ideas? Suggestions?

Here's the code where it's stopping (and the surrounding code):

while(1) { my @ready = (); while(@ready = $sel->can_read(0)) { debug_out("while \$sel->can_read(1)") if $debug > 99; my ($new); foreach $client (@ready) { debug_out("foreach \$client") if $debug > 99; if($client == $server) { debug_out("client == server") if $debug > 99; $new = $server->accept(); $sel->add($new); } else { debug_out("client != server") if $debug > 99; $remote_ip = whos_there($client); debug_out("got remote IP") if $debug > 99; serv_out("Connect from $remote_ip"); $msg_total = 0; debug_out("reset msg total") if $debug > 99; while(<$client>) { debug_out("while <\$client>") if $debug > 99; $message = $_; debug_out("msg = '$message'") if $debug > 99; raw_out($message) if($config{'rawout'} == 1); # for logging: my $msg_length = length($message); debug_out("main: msg_length = $msg_length") if $de +bug > 5; next if $msg_length < 4; $msg_total++; debug_out("main: incr msg total to $msg_total") if + $debug > 99; serv_out("Processing $msg_length bytes from $remot +e_ip\n"); # split the message into segments # we are splitting on carriage returns (NOT newli +ne!) @segments = split /\015/, $message; debug_out("main: split msg into segments") if $deb +ug > 99; # call a sub to loop over the segments process_segment(\@segments, $message, $client); debug_out("main: process segment returns") if $deb +ug > 99; debug_out("main: refreshing logs") if $debug > 99; refresh_logs(); } # end while(<$client>); serv_out("Closing connection from $remote_ip"); } $sel->remove($client); debug_out("Client removed") if $debug > 99; $client->close(); debug_out("Client closed") if $debug > 99; $server = create_socket($config{'port'}); debug_out("server cycled") if $debug > 99; } } }

The create_socket routine prints a message about succesfully creating the listen socket, and returns, that's where we appear to be stopping...(I'm getting the "server cycled" message.)

Anything would be much appreciated.



Replies are listed 'Best First'.
Re: Win32 sockets and disconnects
by cephas (Pilgrim) on Dec 13, 2000 at 03:31 UTC
    Why are you closing your listening socket, then recreating it? Seems like asking for trouble to me. Are you sure that its getting recreated properly? I tried similar code to yours, and on the recreation of the listening socket, it errrored out as the Address already being in use. Is it really necessary to recreate that socket? Also, are you intending on handling multiple clients? If so you'd better change this up a bit. You can see an example of a polling loop that works here

      The reason for the recreation of the socket is that the previous version, which I am being contracted to replace completely, attempted to keep the same socket open forever, which over the internet, is wishful thinking. It could *never* tell if it was disconnected or not, and would therefore never accept a re-connection attempt from a dropped client. In the socket creation routine, I am setting SO_REUSEADDR, so reusing the same address is no problem. Also, the socket creation routine would return error if it couldn't create a new socket, so I'm pretty sure that's all correct.

      As far as multiple clients goes, oddly enough, it will not be handling multiple clients. These are set up on a 1 to 1 ratio, clients to servers. I had actually started out with a polling version, because I also was under the impression that it may have to handle multiple clients (even if not now, but perhaps one day), and I was told that would never happen. *shrug*

      Thanks a lot for the reply.


Re: Win32 sockets and disconnects
by c-era (Curate) on Dec 13, 2000 at 02:58 UTC
    I don't see anything wrong with the code above. From your description it sounds like it may be the client. A way to test this would be to have a second client connect to your server from another pc after you do a ctrl-c on the first client. If the second client can't connect then it is a problem with the server. If it can connect then it is a problem with the client. Let me know what happens.

      We tried what you said, with some definately odd results:

      Started server, started client A.
      Ctrl-C'd client A and restarted it.
      Got the same result we had been getting. It says it connects, sends a message, and sits waiting for an ACK.

      Then, we started client B on another machine. It also says it connects, sends a message, and waits for an ACK.

      Now...if I understand sockets correctly, you can't have 2 connections made to the same port, unless you are handing off connections to another handler for processing, and leaving the original port open for new connects, right?

      Since I'm not doing any of can this be?

      Is this a client problem?
      Is the OS (Win32) doing some internal stuff I'm not aware of?



Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://46331]
Approved by root
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2024-06-16 06:53 GMT
Find Nodes?
    Voting Booth?

    No recent polls found

    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.