Socket send functions only allow you to send strings?

Discussion in 'Ruby' started by Ryan Parmeter, Sep 4, 2007.

  1. I am writing a small TimeP (RFC 868) server to sync time with some
    networking equipment. The equipment that shall go nameless requires the
    use of UDP.

    As far as I can tell, my only option to write to a UDPSocket is to use
    the send method, which takes a string. I need to send a 32bit integer
    representing the date in a UDP packet and I'd love to use something
    like:

    myUDPsocket.send( Time.now.to_i, 0, host, port)

    In my situation I can't change the receiving program to accept a string
    or I could do it that way. I can't convert the integer to a string
    either because that would blow my 32 bit requirement. Does anyone have
    any idea?


    ~Parkingmeter
    --
    Posted via http://www.ruby-forum.com/.
     
    Ryan Parmeter, Sep 4, 2007
    #1
    1. Advertising

  2. On 9/4/07, Ryan Parmeter <> wrote:
    > I am writing a small TimeP (RFC 868) server to sync time with some
    > networking equipment. The equipment that shall go nameless requires the
    > use of UDP.
    >
    > As far as I can tell, my only option to write to a UDPSocket is to use
    > the send method, which takes a string. I need to send a 32bit integer
    > representing the date in a UDP packet and I'd love to use something
    > like:
    >
    > myUDPsocket.send( Time.now.to_i, 0, host, port)
    >
    > In my situation I can't change the receiving program to accept a string
    > or I could do it that way. I can't convert the integer to a string
    > either because that would blow my 32 bit requirement. Does anyone have
    > any idea?
    >
    >
    > ~Parkingmeter
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >


    Try

    ri Array#pack

    [number].pack('i')

    should do the trick.
    pth
     
    Patrick Hurley, Sep 4, 2007
    #2
    1. Advertising

  3. Ryan Parmeter wrote:
    > I am writing a small TimeP (RFC 868) server to sync time with some
    > networking equipment. The equipment that shall go nameless requires the
    > use of UDP.
    >
    > As far as I can tell, my only option to write to a UDPSocket is to use
    > the send method, which takes a string. I need to send a 32bit integer
    > representing the date in a UDP packet and I'd love to use something
    > like:
    >
    > myUDPsocket.send( Time.now.to_i, 0, host, port)
    >
    > In my situation I can't change the receiving program to accept a string
    > or I could do it that way. I can't convert the integer to a string
    > either because that would blow my 32 bit requirement. Does anyone have
    > any idea?


    Strings are just blobs of binary data, when they go through #send. The
    receiver doesn't know it started life as a ruby string.

    If you want structure, use #pack. You'll need to know what byte-order
    the client and server should use to communicate. Assuming big-endian:

    myUDPsocket.send([Time.now.to_i].pack("N"), 0, host, port)

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
     
    Joel VanderWerf, Sep 5, 2007
    #3
  4. Ryan Parmeter

    Guest

    On Wed, 5 Sep 2007, Ryan Parmeter wrote:

    > As far as I can tell, my only option to write to a UDPSocket is to use
    > the send method, which takes a string. I need to send a 32bit integer
    > representing the date in a UDP packet and I'd love to use something
    > like:
    >
    > myUDPsocket.send( Time.now.to_i, 0, host, port)
    >
    > In my situation I can't change the receiving program to accept a string
    > or I could do it that way. I can't convert the integer to a string
    > either because that would blow my 32 bit requirement. Does anyone have
    > any idea?


    A string is just a sequence of bytes. It can be anything.

    In your case, you need to encode a decimal number as returned by
    Time.now.to_i into 32 bits.

    myUDPsocket.send( [Time.now.to_i].pack('i') )

    That may be what you need.

    http://ruby-doc.org/core/classes/Array.html#M002245

    For more information.


    Kirk Haines
     
    , Sep 5, 2007
    #4
  5. In article <>,
    Ryan Parmeter <> writes:
    > I am writing a small TimeP (RFC 868) server to sync time with some
    > networking equipment. The equipment that shall go nameless requires the
    > use of UDP.
    >
    > As far as I can tell, my only option to write to a UDPSocket is to use
    > the send method, which takes a string. I need to send a 32bit integer
    > representing the date in a UDP packet and I'd love to use something
    > like:
    >
    > myUDPsocket.send( Time.now.to_i, 0, host, port)
    >
    > In my situation I can't change the receiving program to accept a string
    > or I could do it that way. I can't convert the integer to a string
    > either because that would blow my 32 bit requirement. Does anyone have
    > any idea?
    >
    > ~Parkingmeter


    Here, I had this script lying about from one of my earlier experiments
    with Ruby sockets:

    - dmw

    ------ start of code -------
    #! /usr/bin/env ruby

    # nettimesvr.rb - implement Time Server for RFC 868

    PROGNAME = 'nettimesvr.rb'
    timeport = Socket.getservbyname('time', 'udp') # port 37
    # timeport = 50037 # for testing
    RFC868_POSIX_ADJMENT = 2_208_988_800 # diff between RFC 868 and POSIX
    POSIX_EPOCH_ADJMENT = Time.gm(1970, 'Jan', 1).to_i

    require 'socket'

    def curnettime()
    return Time.new.to_i + (RFC868_POSIX_ADJMENT - POSIX_EPOCH_ADJMENT)
    end

    port = timeport
    begin
    case ARGV.size
    when 1: port = Integer(ARGV[0])
    when 0: nil
    else; abort "Usage: #{PROGNAME} [ port ]"
    end
    rescue ArgumentError => badarg
    abort "Argument conversion error: #{badarg}"
    end

    puts "Listening on port #{port}\n"

    UDPSocket.open { |sock|
    sock.bind(Socket::INADDR_ANY, port)
    loop do
    # if we try to receive zero bytes, we get an error
    rmthost = sock.recvfrom(1) [1] # no body expected
    puts "Accepted request from #{rmthost [2]}"

    nettime = [ curnettime() ].pack('N')
    sock.send(nettime, 0, rmthost[2], rmthost[1])
    end
    }

    ------ end of code -------

    --
    .. Douglas Wells . Connection Technologies .
    .. Internet: -sp9804- -at - contek.com- .
     
    Douglas Wells, Sep 5, 2007
    #5
    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. Frank Fredstone
    Replies:
    5
    Views:
    768
    Gordon Beaton
    Aug 11, 2006
  2. Jeff
    Replies:
    2
    Views:
    979
    clintonG
    Sep 19, 2006
  3. Laszlo Nagy
    Replies:
    1
    Views:
    5,017
    Mark Wooding
    Jan 27, 2009
  4. Ryan Taylor
    Replies:
    1
    Views:
    710
    Ryan Taylor
    Sep 9, 2004
  5. David Graham

    how do you only allow a popup to popup once

    David Graham, Nov 18, 2003, in forum: Javascript
    Replies:
    4
    Views:
    159
    kaeli
    Nov 18, 2003
Loading...

Share This Page