Vortex Level0 with Ruby

Hello! Recently found this game and it totally got me up. Thou the first
level is extremly straight-forward with C, but i do belive that it is
actually not so difficult with Ruby.
Here is the task:
Your goal is to connect to port 5842 on vortex.labs.overthewire.org and
read in 4 unsigned integers in host byte order. Add these integers
together and send back the results to get a username and password for
level 1.
And here is my code:

require 'socket'

socket = TCPSocket::new( "vortex.labs.overthewire.org", 5842 )
data=Array.new
s=0

4.times do
data = data + socket.recvfrom(4)
end
data.compact!
puts "complete string #{data.inspect}"
data.each { |x| s += x.unpack('L')[0] ; print x.unpack('L')[0], " " }
puts
socket.write s
puts socket.read
socket.close

And it do not solve the subject, please help me to understand where i's
my mistake.

···

--
Posted via http://www.ruby-forum.com/.

socket = TCPSocket::new( "vortex.labs.overthewire.org", 5842 )
data=Array.new
s=0

4.times do
data = data + socket.recvfrom(4)
end
data.compact!
puts "complete string #{data.inspect}"
data.each { |x| s += x.unpack('L')[0] ; print x.unpack('L')[0], " " }
puts
socket.write s
puts socket.read
socket.close

And it do not solve the subject, please help me to understand where i's
my mistake.

Your code, while ugly, is mostly correct from what I can see. A couple suggestions:

1) you're unpacking with "L", which is only correct if you're on the same architecture as the server (little endian). You should use "V" instead to be portable.

2) You're sending back ... what? You may want to implement the echo server from the TCPServer chapter in the pickaxe to see what's going on exactly.

Here is my solution:

···

On Dec 6, 2010, at 13:52 , Eugeni Akmuradov wrote:

class Socket
  def self.open(*args) # 'cuz I don't like ugly
    f = self.class.new(*args)
    yield f
    f.close
  end
end

TCPSocket.open("vortex.labs.overthewire.org", 5842) do |s|
  auth = s.read(16).unpack("V4").inject { |sum, n| sum + n }
  s.write [auth].pack("V")
  pass = s.read
  p pass
end

thanx, but i also dont't get this part

class Socket
def self.open(*args) # 'cuz I don't like ugly
f = self.class.new(*args)
yield f
f.close
end
end

is it absolutely necessary ?

TCPSocket.open("vortex.labs.overthewire.org", 5842) do |s|
auth = s.read(16).unpack("V4").inject { |sum, n| sum + n }
s.write [auth].pack("V")
pass = s.read
p pass
end

···

--
Posted via http://www.ruby-forum.com/\.

i just need some time :slight_smile:
here you basically ovverides the base class for the TCPSocket, and than
creating an instance of that class, which have an modified function open
to close the socket, right ?

···

--
Posted via http://www.ruby-forum.com/.

It's not necessary. It's a convenience method (similar to File#open)
so that you don't need to explicitly close the socket after you are
finished with it. In order to be more robust, the usual thing is to
close the socket in an ensure block, so that even if there's an
exception, the socket gets closed.

Jesus.

···

On Tue, Dec 7, 2010 at 9:29 AM, Eugeni Akmuradov <e.akmuradov@gmail.com> wrote:

thanx, but i also dont't get this part

class Socket
def self.open(*args) # 'cuz I don't like ugly
f = self.class.new(*args)
yield f
f.close
end
end

is it absolutely necessary ?

it is code. on a puzzle. of course it isn't absolutely necessary. The important part is that 1) it works and 2) it is a lot cleaner and more maintainable. I suggest focusing on 1 and applying it to your code. 2 will resolve itself with time.

···

On Dec 7, 2010, at 00:29 , Eugeni Akmuradov wrote:

thanx, but i also dont't get this part

class Socket
def self.open(*args) # 'cuz I don't like ugly
f = self.class.new(*args)
yield f
f.close
end
end

is it absolutely necessary ?

In Ruby, classes are open. This means that at any time, you can reopen
the class to do stuff to the class, such as adding methods. Any
instance of that class will have that method available, even the ones
created before the change.

In this case, Ryan is adding a class method that internally creates an
instance of the TCPSocket class, and yields it to a block, ensuring
that after calling the block, the socket is closed.

Jesus.

···

On Tue, Dec 7, 2010 at 11:22 PM, Eugeni Akmuradov <e.akmuradov@gmail.com> wrote:

i just need some time :slight_smile:
here you basically ovverides the base class for the TCPSocket, and than
creating an instance of that class, which have an modified function open
to close the socket, right ?

good catch. thanks

···

On Dec 7, 2010, at 00:48 , Jesús Gabriel y Galán wrote:

In order to be more robust, the usual thing is to
close the socket in an ensure block, so that even if there's an
exception, the socket gets closed.