Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Re: Socket hangs

by mikeock (Hermit)
on Dec 23, 2005 at 16:25 UTC ( #518781=note: print w/replies, xml ) Need Help??

in reply to Socket hangs

Whenever I do a socket connection I loop through the socket. You can send a shutdown($local, 1) to read all of the info.

From the camel book: This is used to close only your side of the connection, so that the remote gets an end of file, but you can still read data coming from the server.

Replies are listed 'Best First'.
Re^2: Socket hangs
by navarro (Initiate) on Dec 23, 2005 at 18:13 UTC
    Well, i tryed to use shutdown() but i`ve got same behavior but in other hand i could make it work but still have some small problems, take a look:
    # ./ Connected from: Command> >uname Linux Command> id nobody uid=99(nobody) gid=99(nogroup) groups=99(nogroup),98(nobody) Command>
    That is ok, but in some commands (i dont know why) i can execute them sucessfully and them i`ve freeze again, look:
    Command> touch test
    And look what happens if i use ";" followed by some other command:
    Command> touch test ; ls test Command>
    Here is the code:
    sub listen() { $local = IO::Socket::INET->new(Listen=>1, Proto=>'tcp', LocalAddr=>'eth0' LocalPort=>5000, ReuseAddr=>1,) or die "$!"; $local->autoflush(1); $addr = $local->accept(); $remotehost = $addr->peerhost ; $remoteport = $addr->peerport ; print "Connected from: $remotehost:$remoteport\n"; print "Command> "; while($comm = <STDIN>) { print $addr $comm; sub closeback() {exit(0)} while(sysread($addr,$buffer,1024)) { print $buffer; last; } print "Command> "; } }
    Any tip? thanks.

      First of all, navarro, what behaviour are you looking for? Your first version accepts a single connection from the server and expects to see a sequence of multiple commands being received over it, the second changes to one new socket accept per command, and the last one reverts to behaviour that is almost like the first one except that it has an additional bug (see below). Which one are you looking for?

      If you want to receive multiple commands one after another over the same socket, then the client (the side that executes the command) will have to use some kind of scheme to mark the end of the results of that command so that the server knows to stop reading output and send a new command. You expressly do not want to use shutdown for the purpose in this case because you want the socket to stay open bidirectionally for the next command. In this case you should look at how some of the common internet protocols like SMTP do it: schemes like dot stuffing. Any kind of quoting scheme will do if the command output can contain arbitrary data, and if the command output cannot contain arbitrary data, then some marker that consists of impossible data for the command will do. When you receive this marker, you would exit from the read loop (it doesn't matter whether it's read or sysread). Your most recent example does not do this properly: it exits from the while loop (via last) after the first sysread unconditionally (you may as well have not had a loop there). You may or may not have finished collecting all of the output from the command at that point!

      If, on the other hand, you want to accept only one command per socket and open a new socket for the next command, then it becomes easier. The client end (which you have not shown code for) should shutdown the socket after it has finished sending the command output and the server will then see an EOF in its read loop. This is analogous to what FTP does with its dedicated data TCP connection for each data transfer.

      More importantly than any of this, you should seriously consider how secure all of this is! You have already noticed how you can send multiple commands by seperating them with a semicolon, which I guess means you are passing the commands to a shell on the client side, but even if you were not doing that, your client program appears to be a "please crack me" client. It connects to a server that is not required to authenticated itself, via an unprotected channel, and proceeds to execute any arbitrary command that comes over that socket. Are you sure you want to do this?

        First at all, i want it to be bidirecional. So shutdown() does not ser +ve to me until now. About your security question you have said that server does no require + authentication. It is not right, the server is running as port knock +ing, in other words it does not open any port until it recieves (from + client) the correct sequence of udp packets (Net::RawIP and Net::Pca +pUtils) from correct source ip:port(s). So it is a way of authenticat +ion. Lately i will use some kind of user/password and SSL i guess. Im still beginning to code it and i just can get over after fix these +bugs.
      I have never gotton the sysread to function properly on a socket. All of the implementations that I have use the shutdown command.

      That is why I recomed the shutdown($socketname, 1) to return the data.

      My only experience with sockets is when i connect send a command dissconnect and then reconenct for another command.

        I understand. In my case i need to stay connected becouse it is look like an interative shell. Thanks for advance mikeock!

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (2)
As of 2023-03-25 17:52 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (63 votes). Check out past polls.