Forum: Ruby socket from python to ruby

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D2f75a670c0a80156c02752baae96a6a?d=identicon&s=25 Devis Battisti (batdevis)
on 2008-10-29 15:05
I'd want to port this code from python to ruby:

self.sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
self.sckt.bind((self.CFG['smsc']['local_host'],
self.CFG['smsc']['local_port']))
self.sckt.connect((self.CFG['smsc']['remote_host'],
self.CFG['smsc']['remote_port']))
self.sckt.send(mex)
recv = self.sckt.recv(4096)
self.sckt.close()

The remote host is a router for an SMSC service.
The script is tested and works correctly.
I don't understand if I've to create a client or a server socket...

bye

Devis_
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-10-29 15:44
Devis Battisti wrote:
> I'd want to port this code from python to ruby:
>
> self.sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
> self.sckt.bind((self.CFG['smsc']['local_host'],
> self.CFG['smsc']['local_port']))
> self.sckt.connect((self.CFG['smsc']['remote_host'],
> self.CFG['smsc']['remote_port']))
> self.sckt.send(mex)
> recv = self.sckt.recv(4096)
> self.sckt.close()
>
> The remote host is a router for an SMSC service.
> The script is tested and works correctly.
> I don't understand if I've to create a client or a server socket...

Since you are using TCP and calling 'connect', it's a client socket.

However, they have (unusually) decided to bind the socket to a specific
local port. This might be because of firewall rules.

Without this you could just do:

   s = TCPSocket.new(cfg.remote_host, cfg.remote_port)
   s.write(mex)
   recv = s.read(4096)

If you really need to bind the local port for an outbound connection, I
think you'll have to use the lower-level Socket class directly, which is
not particularly well documented, but should correspond roughly to your
python code. Unfortunately you'll need to do some sockaddr packing.

http://www.ruby-doc.org/docs/ProgrammingRuby/html/...
D2f75a670c0a80156c02752baae96a6a?d=identicon&s=25 Devis Battisti (batdevis)
on 2008-10-29 18:54
> However, they have (unusually) decided to bind the socket to a specific
> local port. This might be because of firewall rules.

yes, I thin so.

>
> Without this you could just do:
>
>    s = TCPSocket.new(cfg.remote_host, cfg.remote_port)
>    s.write(mex)
>    recv = s.read(4096)
>

no, it doesn't work: it remains in attemp of response.


> If you really need to bind the local port for an outbound connection, I
> think you'll have to use the lower-level Socket class directly, which is
> not particularly well documented, but should correspond roughly to your
> python code. Unfortunately you'll need to do some sockaddr packing.
>
> http://www.ruby-doc.org/docs/ProgrammingRuby/html/...

thanks for the answer, I will continue to try...

Devis_
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-10-29 20:56
It's not so hard after all:

require 'socket'
local_host = "127.0.0.1"
local_port = 1234
remote_host = "127.0.0.1"
remote_port = 80
s = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
s.bind(Socket.pack_sockaddr_in(local_port, local_host))
s.connect(Socket.pack_sockaddr_in(remote_port, remote_host))
s.write "GET / HTTP/1.0\r\n\r\n"
puts s.recv(4096)

I found useful examples at
http://www.ruby-doc.org/stdlib/libdoc/socket/rdoc/...
http://www.ruby-doc.org/stdlib/libdoc/socket/rdoc/...

The documentation is much better than when I last looked - although
Socket.new doesn't seem to be shown.

HTH,

Brian.
Cf7cd97cdc8ed7d4ae92965b24f0dfad?d=identicon&s=25 Stefan Rusterholz (apeiros)
on 2008-10-30 13:36
Brian Candler wrote:
> However, they have (unusually) decided to bind the socket to a specific
> local port. This might be because of firewall rules.
>
> Without this you could just do:
>
>    s = TCPSocket.new(cfg.remote_host, cfg.remote_port)

TCPSocket::open accepts local host and port args, from the docs (1.8.7):
>> TCPSocket.new(remote_host, remote_port, local_host=nil, local_port=nil)

Regards
Stefan
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-10-30 15:51
Stefan Rusterholz wrote:
> TCPSocket::open accepts local host and port args, from the docs (1.8.7):

Thank you. If this were just 1.8.7 then I wouldn't be interested, but
actually it works for 1.8.6 too.

My "Programming Ruby" (2nd edition, p771) lists only the two parameters
for TCPSocket.new. That book was written against 1.8.2, so looks like it
was added some time after then.
D2f75a670c0a80156c02752baae96a6a?d=identicon&s=25 Devis Battisti (batdevis)
on 2008-10-30 16:48
Thanks to everybody, it works!
This topic is locked and can not be replied to.