checking connection to server:port [socket]

Discussion in 'Ruby' started by Kr Alfabeta, Apr 15, 2008.

  1. Kr Alfabeta

    Kr Alfabeta Guest

    hi,

    I have been googling for about two hours to solve problem with sockets
    connect method. I need to check connection to server
    www.example.com:xxxx (UDP)
    but the problem is that the answer (connected, refused or smth..)
    returns only with @socket.print "smth" + @socket.recv. (@socket.connect
    only takes the port and address for using when @socket.print is called)

    The problem is that I don't know what I should print there. I just need
    to check the connection.

    In PHP there are very simple solution:
    $fp = fpsockopen(....)
    if ($fp) return true; else return false;

    and just then you can send and receive data.
    Maybe there are any solutions within sockets?

    Sorry for my english! :)
    --
    Posted via http://www.ruby-forum.com/.
     
    Kr Alfabeta, Apr 15, 2008
    #1
    1. Advertising

  2. Kr Alfabeta wrote:
    > hi,
    >
    > I have been googling for about two hours to solve problem with sockets
    > connect method. I need to check connection to server
    > www.example.com:xxxx (UDP)
    > but the problem is that the answer (connected, refused or smth..)
    > returns only with @socket.print "smth" + @socket.recv. (@socket.connect
    > only takes the port and address for using when @socket.print is called)
    >
    > The problem is that I don't know what I should print there. I just need
    > to check the connection.
    >
    > In PHP there are very simple solution:
    > $fp = fpsockopen(....)
    > if ($fp) return true; else return false;
    >
    > and just then you can send and receive data.
    > Maybe there are any solutions within sockets?
    >
    > Sorry for my english! :)
    >


    If socket.connect does not succeed, it will raise an error, otherwise
    you should be good to go. See the documentation here
    (http://ruby-doc.org/stdlib/libdoc/socket/rdoc/classes/Socket.html) and
    here (http://ruby-doc.org/stdlib/libdoc/socket/rdoc/classes/Socket.html).

    Does that help?

    -Justin
     
    Justin Collins, Apr 16, 2008
    #2
    1. Advertising

  3. Kr Alfabeta

    Kr Alfabeta Guest

    Re: checking connection to server:port


    > If socket.connect does not succeed, it will raise an error, otherwise
    > you should be good to go. See the documentation here
    > (http://ruby-doc.org/stdlib/libdoc/socket/rdoc/classes/Socket.html) and
    > here
    > (http://ruby-doc.org/stdlib/libdoc/socket/rdoc/classes/Socket.html).
    >
    > Does that help?
    >
    > -Justin


    Well, I was trying this but it returns the same response when it's
    possible to connect to IP but not to port (example: port 1234 not binded
    in server but the response is the same as with binded port 80)
    --
    Posted via http://www.ruby-forum.com/.
     
    Kr Alfabeta, Apr 16, 2008
    #3
  4. Kr Alfabeta

    James Tucker Guest

    Re: checking connection to server:port

    On 16 Apr 2008, at 13:08, Kr Alfabeta wrote:
    >
    >> If socket.connect does not succeed, it will raise an error, otherwise
    >> you should be good to go. See the documentation here
    >> (http://ruby-doc.org/stdlib/libdoc/socket/rdoc/classes/Socket.html)
    >> and
    >> here
    >> (http://ruby-doc.org/stdlib/libdoc/socket/rdoc/classes/Socket.html).
    >>
    >> Does that help?
    >>
    >> -Justin

    >
    > Well, I was trying this but it returns the same response when it's
    > possible to connect to IP but not to port (example: port 1234 not
    > binded
    > in server but the response is the same as with binded port 80)


    UDP is connectionless, unreliable, and will not report errors to you
    for foreign "connections". I am unsure as to why the api is like it
    is, other than that it follows iirc, the bsd sockets api.

    I know there's a connect method, but that is merely for convenience.
    Look at UDP(4) (that is, man 4 udp).

    The only reason you would be getting strange errors is if you're
    testing over localhost. Errors for UDP packets are irregular at best:

    >> raggi@mbk:~$ irb
    >> require 'socket'

    => true
    >> sock = UDPSocket.new

    => #<UDPSocket:0x8320c>
    >> sock.connect('beith', 1234)

    => 0
    >> sock.write('foo')

    => 3
    >> sock.write('foo')

    Errno::ECONNREFUSED: Connection refused
    from (irb):5:in `write'
    from (irb):5
    from :0
    >> sock.write('foo')

    => 3
    >> sock.write('foo')

    Errno::ECONNREFUSED: Connection refused
    from (irb):7:in `write'
    from (irb):7
    from :0

    Again, what the man page is saying should make the above more clear.

    Somewhat reminds me of the time a company asked me to use the packet
    arrival order of UDP data in order to reconstruct long messages, lol.


    >
    > --
    > Posted via http://www.ruby-forum.com/.
    >
     
    James Tucker, Apr 16, 2008
    #4
  5. Kr Alfabeta

    Kr Alfabeta Guest

    Re: checking connection to server:port

    Thank you for replay. Well, in PHP there is a function which works fine
    (fsockopen) so I need function in ruby working in the same way as that
    function in PHP.

    I can see a lot of strange responses and so on but I still need the
    solution :)
    --
    Posted via http://www.ruby-forum.com/.
     
    Kr Alfabeta, Apr 16, 2008
    #5
  6. Kr Alfabeta

    Kr Alfabeta Guest

    Re: checking connection to server:port


    > i think you just want to check a udp connection to a udp server. no
    > problem.
    >
    > require 'socket'
    > s = UDPSocket.new
    > s.connect("10.10.10.10", 10101)
    > puts "you are connected" #<-- if you get here, you are connected
    >


    when I trying to connect with PHP (fsockopen) it fails: Warning:
    fsockopen() [function.fsockopen]: unable to connect to xxx.xx.xx.xx:2555
    (No route to host)

    RUBY:

    irb(main):001:0> require 'socket'
    => true
    irb(main):002:0> s = UDPSocket.new
    => #<UDPSocket:0xb7d3c590>
    irb(main):003:0> s.connect('xxx.xx.xx.xx', 2555)
    => 0
    irb(main):004:0> puts 'ok'
    ok
    => nil

    I think this example really shows the problem about which I am talking
    :)
    --
    Posted via http://www.ruby-forum.com/.
     
    Kr Alfabeta, Apr 17, 2008
    #6
  7. Kr Alfabeta

    James Tucker Guest

    On 17 Apr 2008, at 03:40, Pe=F1a, Botp wrote:
    > From:
    > # [mailto:] On Behalf Of Kr Alfabeta
    > # ...connect method. I need to check connection to server
    > # www.example.com:xxxx (UDP)
    > # ...
    > # The problem is that I don't know what I should print there.
    > #
    > # I just need to check the connection.
    > # In PHP there are very simple solution:
    > # $fp =3D fpsockopen(....)
    > # if ($fp) return true; else return false;
    >
    > i think you just want to check a udp connection to a udp server. no =20=


    > problem.
    >
    > require 'socket'
    > s =3D UDPSocket.new
    > s.connect("10.10.10.10", 10101)
    > puts "you are connected" #<-- if you get here, you are connected
    >
    > the reason the above works is that s.connect will raise an exception =20=


    > if it cannot connect and you'll have to catch the reason by rescue-=20
    > ing it.


    Interesting idea, however, as I said in my last post, this is really =20
    not possible to do reliably with UDP (in fact, at all in reality, as =20
    the api will "lie"). UDP is stateless and connectionless, there are no =20=

    connections. The PHP api was essentially lying to the OP, and ruby =20
    will too (in fact, it's not a lie, it's PEBKAC, and the man page for =20
    UDP(4) will explain what I'm telling you guys better than I have, =20
    please do read it):

    >> require 'socket'

    =3D> true
    >> sock =3D UDPSocket.new

    =3D> #<UDPSocket:0x8320c>
    >> sock.connect('some.really.long.domain.that.doesnt.exist', 1234)

    SocketError: getaddrinfo: nodename nor servname provided, or not known
    from (irb):3:in `connect'
    from (irb):3
    from :0
    >> sock.connect('127.0.0.220',1234) # Please note carefully that this =20=


    IP does not exist, and there's no machine on it.
    =3D> 0
    >> `ping -c 1 127.0.0.220`

    =3D> "PING 127.0.0.220 (127.0.0.220): 56 data bytes\n\n--- 127.0.0.220 =20=

    ping statistics ---\n1 packets transmitted, 0 packets received, 100% =20
    packet loss\n"
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3

    # N.N.B. No failures, at all, and yet there should be if there was a =20
    'connection' semantic in the protocol.

    >> `ping -c 1 192.168.253.253`

    =3D> "PING 192.168.253.253 (192.168.253.253): 56 data bytes\n\n--- =20
    192.168.253.253 ping statistics ---\n1 packets transmitted, 0 packets =20=

    received, 100% packet loss\n"

    # N.N.B. The ping failed, see?

    >> sock.connect('192.168.253.253', 1234) # Please note carefully that =20=


    this IP does not exist, and there's no machine on it.
    =3D> 0
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3

    # Still no failures...

    >> sock.connect('67.207.151.240', 1234) # Please note carefully that =20=


    this IP does not exist, and there's no machine on it *I think*. See =20
    note at end of mail.
    =3D> 0
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3
    >> sock.write('foo')

    =3D> 3

    Both of the above "connections" should have "failed" (they don't =20
    because there are no connections, and there are no 'failures' for UDP, =20=

    the protocol is dumb as hell and will never know, unless the packets =20
    are actively rejected by a host at the receiving IP address), there =20
    are no machines on those IPs. I've provided multiple examples on =20
    different ip classes and you'll notice that the DNS error is a *DNS* =20
    error, not a UDP socket connect. UDP doesn't "connect".

    I have since looked up why the "connect()" function even exists, and =20
    it is for the sole purpose of reserving a source port for sending data =20=

    (which may aid in remote stateful logic, where the application layer =20
    protocol is not completely stateless, even though UDP is).


    > # and just then you can send and receive data.
    > # Maybe there are any solutions within sockets?
    >
    > socket programming in ruby is very complete and ranges from low =20
    > level basic socket programming to high level uri... you might want =20
    > to read the ruby programming language book..


    And I'll repeat, please read UDP(4).

    That is `man 4 udp`. Other good references can be found on wikipedia:

    http://en.wikipedia.org/wiki/User_Datagram_Protocol

    It's very very important that the OP realises that their code in =20
    whatever language, is not doing what they think.

    > kind regards -botp



    P.S. The last IP, the one that's internet public I chose by searching =20=

    for an IP that didn't respond to ICMP echo, so it may actually exist, =20=

    nonetheless, it was the first empty publicly routable IP I could find =20=

    that appeared to be down, without actually doing a massive scan range =20=

    over the internet (which is frowned upon). Please don't abuse that IP, =20=

    I don't know who it belongs to, nor do I care at this point.=
     
    James Tucker, Apr 17, 2008
    #7
  8. Kr Alfabeta

    James Tucker Guest

    Re: checking connection to server:port

    On 17 Apr 2008, at 05:34, Kr Alfabeta wrote:
    >
    >> i think you just want to check a udp connection to a udp server. no
    >> problem.
    >>
    >> require 'socket'
    >> s = UDPSocket.new
    >> s.connect("10.10.10.10", 10101)
    >> puts "you are connected" #<-- if you get here, you are connected
    >>

    >
    > when I trying to connect with PHP (fsockopen) it fails: Warning:
    > fsockopen() [function.fsockopen]: unable to connect to xxx.xx.xx.xx:
    > 2555
    > (No route to host)
    >
    > RUBY:
    >
    > irb(main):001:0> require 'socket'
    > => true
    > irb(main):002:0> s = UDPSocket.new
    > => #<UDPSocket:0xb7d3c590>
    > irb(main):003:0> s.connect('xxx.xx.xx.xx', 2555)
    > => 0
    > irb(main):004:0> puts 'ok'
    > ok
    > => nil
    >
    > I think this example really shows the problem about which I am talking
    > :)


    All that is doing, is checking that the IP is routable. Nothing more.

    This has nothing to do with the port availability or providing you
    with *any* information as to whether or not the application is
    available at the other end. Please carefully read my other responses
    and the referenced manuals and documentation.

    What you're asking for is impossible.

    >
    > --
    > Posted via http://www.ruby-forum.com/.
    >
     
    James Tucker, Apr 17, 2008
    #8
  9. Kr Alfabeta

    Kr Alfabeta Guest

    Re: checking connection to server:port

    Thank you for all replays. Now everything is more clear. In php manual:

    UDP sockets will sometimes appear to have opened without an error, even
    if the remote host is unreachable. The error will only become apparent
    when you read or write data to/from the socket. The reason for this is
    because UDP is a "connectionless" protocol, which means that the
    operating system does not try to establish a link for the socket until
    it actually needs to send or receive data.

    So in conclusion there is no way to check that UDP port is working or
    not? Maybe there is a common query which you can send by UDP and then
    receive any response?
    --
    Posted via http://www.ruby-forum.com/.
     
    Kr Alfabeta, Apr 17, 2008
    #9
  10. Kr Alfabeta

    Avdi Grimm Guest

    Re: checking connection to server:port

    On Thu, Apr 17, 2008 at 7:58 AM, Kr Alfabeta <> wrote:
    > So in conclusion there is no way to check that UDP port is working or
    > not? Maybe there is a common query which you can send by UDP and then
    > receive any response?


    There is no query/response in UDP. It's fire-and-forget. The only
    way you can get a "response" is if you control the receiving computer
    and can put some code on it to fire a message back to a receiving port
    on the sender after it receives a message. Of course, in UDP there's
    no guarantee that the reply will arrive...

    Having once implemented a reliable multicasting protocol on top of UDP
    (long story), I can say this: don't try to treat UDP as a
    connectional protocol unless you have a really, really good reason.
    That's what TCP is for.

    --
    Avdi

    Home: http://avdi.org
    Developer Blog: http://avdi.org/devblog/
    Twitter: http://twitter.com/avdi
    Journal: http://avdi.livejournal.com
     
    Avdi Grimm, Apr 17, 2008
    #10
  11. Kr Alfabeta

    James Tucker Guest

    Re: checking connection to server:port

    On 17 Apr 2008, at 12:58, Kr Alfabeta wrote:
    > Thank you for all replays. Now everything is more clear. In php
    > manual:
    >
    > UDP sockets will sometimes appear to have opened without an error,
    > even
    > if the remote host is unreachable. The error will only become apparent
    > when you read or write data to/from the socket. The reason for this is
    > because UDP is a "connectionless" protocol, which means that the
    > operating system does not try to establish a link for the socket until
    > it actually needs to send or receive data.


    Typical.

    This is wrong. "connectionless" needs no quotes, it *is*
    connectionless. The operating system never ever "establishes a link"
    with UDP. It merely constructs a UDP packet and passes it to the
    appropriate next-hop router (or the target ip if on the same subnet),
    and forgets about it. There is no link, there is no connection. With
    UDP there never will be. That's the point of the protocol.

    > So in conclusion there is no way to check that UDP port is working or
    > not? Maybe there is a common query which you can send by UDP and then
    > receive any response?


    No, you can check for a particular response *if* the application
    protocol is designed to send one, *or* you can be lucky and the target
    IP address will *actively refuse* the packet, in which case you get
    some notification back on some systems. This is not complete
    'checking' for a working application, *at all*. If the box goes
    completely offline, and there are no devices doing anything outside of
    the UDP protocol spec, then you'll get no notification of the failure
    to deliver. Nothing, nada, complete silence.

    A timeout solution waiting for a response may be appropriate for
    *certain* application level protocols from which you might expect a
    response to your packets, however, this is really completely not the
    purpose of UDP.

    Why are you trying to check that a UDP port is open? And if you need
    reliable communications you should be using TCP.

    >
    > --
    > Posted via http://www.ruby-forum.com/.
    >
     
    James Tucker, Apr 17, 2008
    #11
  12. Kr Alfabeta

    James Tucker Guest

    Re: checking connection to server:port

    On 17 Apr 2008, at 14:20, Park Heesob wrote:
    >>

    > Try this:
    >
    > require 'timeout'
    > require 'socket'
    >
    > port = 1000
    > server = '127.0.0.1'
    >
    > s = UDPSocket.new
    > s.connect(server,port)
    > s.write("\0")
    > begin
    > Timeout.timeout(1){s.read}
    > rescue Errno::ECONNREFUSED => e
    > puts "closed"


    Tells you a machine received it (hopefully the real one ;) ), and that
    the port was not open when the packet was received. You do not know
    when that was, or which packet it was.

    > rescue Timeout::Error
    > puts "open"


    Tells you that the machine did no actively refuse it, and *nothing
    else*. Many strictly configured firewalls will result in this for all
    UDP ports, at which point you really know nothing at all form this
    result, and it's highly likely they're all closed in reality, with the
    default rule being:

    protocol:udp source:any destination:any action:drop

    or *extremely* similar.

    >
    > ensure
    > s.close


    All this does is close the local source port, it does not close any
    "connection".

    >
    > end
     
    James Tucker, Apr 17, 2008
    #12
  13. Kr Alfabeta

    Kr Alfabeta Guest

    Re: checking connection to server:port


    >
    > irb(main):095:0> t=TCPSocket.new "10.2.10.1",80
    > => #<TCPSocket:0xb7de652c>
    > irb(main):096:0> t=TCPSocket.new "10.2.10.11",80
    > Errno::EHOSTUNREACH: No route to host - connect(2)
    >


    Thank you for help guys! :) The specification of product says that
    "connection" available through UDP but you can check the connection
    using TCP... interesting... Anyway, thanks!
    --
    Posted via http://www.ruby-forum.com/.
     
    Kr Alfabeta, Apr 18, 2008
    #13
  14. Kr Alfabeta

    Slan Dizier Guest

    [Note: parts of this message were removed to make it a legal post.]

    unsubscribe
     
    Slan Dizier, May 8, 2008
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Berlin  Brown
    Replies:
    3
    Views:
    1,240
    Berlin Brown
    Jul 1, 2005
  2. Laszlo Nagy
    Replies:
    1
    Views:
    4,917
    Mark Wooding
    Jan 27, 2009
  3. Jean-Paul Calderone
    Replies:
    0
    Views:
    991
    Jean-Paul Calderone
    Jan 27, 2009
  4. John Ramsden

    Opening a socket connection on a serial port

    John Ramsden, Jul 16, 2003, in forum: Perl Misc
    Replies:
    2
    Views:
    227
    John Ramsden
    Jul 17, 2003
  5. Replies:
    1
    Views:
    599
    Toni Erdmann
    Mar 2, 2005
Loading...

Share This Page