Ruby Newbie's Question: Sockets - searching for equivalent to a perl programme

Hi all,

I have been desperately trying to convert the following perl programme
to Ruby. What should I use for the functions sockaddr_in (maybe the
famous pack(“snCaaaa8”) ?) and syswrite.

Thank for assisting me!
Johannes

Here’s the perl programme I have been trying to convert to Ruby

use IO::Socket;

snip

$ServerPort=8530;
$scheme_exp=‘(ivel-window-get-active-vref)’;

if (!defined $Proto) {
$iaddr = inet_aton(hostname());
$Proto = getprotobyname(‘tcp’);
}

$paddr = sockaddr_in($ServerPort, $iaddr);

#Socket settings.

if (!(socket(SOCK, &PF_INET, &SOCK_STREAM, $Proto))) {
warn “socket: $!\n”;
return “socket: $!\n”;
}

if (!(defined $ServerPort) || !(connect(SOCK,$paddr))) {
print “Error: could not open socket to Visual.\n”;
print “Probably because Visual either crashed or was killed.\n”;
exit 0;
}

select(SOCK);
$|=1;
select(STDOUT);
$cmd = “#S(netutl-client-msg-header
netutl-client-msg-type/gui-blocking "Perl client")\r\n”;
syswrite(SOCK,$cmd,length($cmd));

select(SOCK);
$|=1;
select(STDOUT);
$cmd = “($scheme_exp)\r\n”;
syswrite(SOCK,$cmd,length($cmd));

SOCK → autoflush();

$ret_val = “”;

while() {
$ret_val .= $_;
}

shutdown(SOCK,2);
chomp($ret_val);
return($ret_val);

···

Johannes Steigerwald | Océ Printing Systems GmbH, TEC35|
phone: +49-8121-72-4912 | Siemensallee 2 |
fax: +49-8121-72-3173 | D-85586 Poing - Germany |
johannes.steigerwald@ops.de | www.oce.com |


I have been desperately trying to convert the following perl programme
to Ruby. What should I use for the functions sockaddr_in (maybe the
famous pack("snCaaaa8") ?) and syswrite.

Well, look at the class TCPSocket

   http://www.rubycentral.com/book/lib_network.html#TCPSocket.new

   http://www.ruby-lang.org/en/man-1.4/socket.html#TCPSocket

Guy Decoux

Thanks Guy,

now, while the perl programme works perfectly fine, I have difficulties
with the TCPSocket version. I tried:

irb(main):029:0* t=TCPSocket.new(‘localhost’,8530)
#TCPSocket:0x163000
irb(main):030:0> t.addr
[“AF_INET”, 61501, “127.0.0.1”, “127.0.0.1”]
irb(main):031:0> t.peeraddr
[“AF_INET”, 8530, “127.0.0.1”, “127.0.0.1”]
irb(main):032:0> t.puts(“#$(netutl-client-msg-header
netutl-client-msg-type/gui-blocking "Perl client")\r\n”)
nil
irb(main):033:0> t.puts(“(ivel-window-get-active-vref)\r\n”)
nil
irb(main):034:0> t.gets
Errno::ECONNRESET: Connection reset by peer
from (irb):34:in `gets’
from (irb):34
irb(main):035:0>

I also tried recvfrom instead of gets, no matter how, each time the
connection gets reset.
The I replaced ‘localhost’ with the servers actual IP address, getting
the same result.

The perl programme always gets a correct answer from the server.

Johannes

ts wrote:

···

I have been desperately trying to convert the following perl programme
to Ruby. What should I use for the functions sockaddr_in (maybe the
famous pack(“snCaaaa8”) ?) and syswrite.

Well, look at the class TCPSocket

http://www.rubycentral.com/book/lib_network.html#TCPSocket.new

http://www.ruby-lang.org/en/man-1.4/socket.html#TCPSocket

Guy Decoux

Johannes Steigerwald | Océ Printing Systems GmbH, TEC35|
phone: +49-8121-72-4912 | Siemensallee 2 |
fax: +49-8121-72-3173 | D-85586 Poing - Germany |
johannes.steigerwald@ops.de | www.oce.com |


irb(main):029:0* t=TCPSocket.new('localhost',8530)
#<TCPSocket:0x163000>
irb(main):030:0> t.addr
["AF_INET", 61501, "127.0.0.1", "127.0.0.1"]
irb(main):031:0> t.peeraddr
["AF_INET", 8530, "127.0.0.1", "127.0.0.1"]
irb(main):032:0> t.puts("#$(netutl-client-msg-header
netutl-client-msg-type/gui-blocking \"Perl client\")\r\n")
nil

well, the difference with the perl program is perhaps here

select(SOCK);
$|=1;
select(STDOUT);

it force a flush after every print, try to add

   t.sync = true

svg% ri IO#sync=
--------------------------------------------------------------- IO#sync=
     ios.sync = aBoolean -> aBoolean

···

------------------------------------------------------------------------
     Sets the ``sync mode'' to true or false. When sync mode is true,
     all output is immediately flushed to the underlying operating
     system and is not buffered internally. Returns the new state.
        f = File.new("testfile")
        f.sync = true

svg%

p.s.: you use 1.6.8, no ?

Guy Decoux

did you considred that ‘puts’ adds a line separatore by itself ?
You should be using print or set the default line saparetor to \r\n

···

il Mon, 29 Sep 2003 14:28:08 +0200, Johannes Steigerwald johannes.steigerwald@ops.de ha scritto::

Thanks Guy,

now, while the perl programme works perfectly fine, I have difficulties
with the TCPSocket version. I tried:

irb(main):029:0* t=TCPSocket.new(‘localhost’,8530)
#TCPSocket:0x163000
irb(main):030:0> t.addr
[“AF_INET”, 61501, “127.0.0.1”, “127.0.0.1”]
irb(main):031:0> t.peeraddr
[“AF_INET”, 8530, “127.0.0.1”, “127.0.0.1”]
irb(main):032:0> t.puts(“#$(netutl-client-msg-header
netutl-client-msg-type/gui-blocking "Perl client")\r\n”)

did you considred that 'puts' adds a line separatore by itself ?
You should be using print or set the default line saparetor to \r\n

#puts add a line separator if it don't exist :

svg% ruby -e 'puts "a"; puts "b\n"; puts "c\n\n"'
a
b
c

svg%

Guy Decoux

ts wrote:

did you considred that ‘puts’ adds a line separatore by itself ?
You should be using print or set the default line saparetor to \r\n

#puts add a line separator if it don’t exist :

svg% ruby -e ‘puts “a”; puts “b\n”; puts “c\n\n”’
a
b
c

svg%

Guy Decoux

Thanks and sorry for not returning immediately.

I replaced puts with print and that clumsy string (#S(netutl…)) I
have to send to the server. Unfortunately I got the same results
(Connection reset by peer).

Any more ideas?

Thanks Johannes

···

Johannes Steigerwald | Océ Printing Systems GmbH, TEC35|
phone: +49-8121-72-4912 | Siemensallee 2 |
fax: +49-8121-72-3173 | D-85586 Poing - Germany |
johannes.steigerwald@ops.de | www.oce.com |