I am writing a program in which one script (the python script) hosts a server, and the ruby script then connects, after doing so, the python script displays a prompt and sends the data to the connected ruby client, the ruby program then executes the command via system function, my error is the command only executes when you end the connection on the server (python script) so I can send only one command, then end the connection and the ruby script then executes, I want it to run and execute the commands as it receives them. Here are the scripts:
python:
#!/usr/bin/env python
import socket
import time
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(('192.168.1.104',567))
sock.listen(1)
(client,(ip,port))=sock.accept()
print('[*] Connection from {} via port {}').format(ip,port)
while True:
cmd = raw_input("# ")
client.send(str(cmd))
Ruby:
class C
attr_accessor :clr
end
r = C.new
r.clr = "\033[0;31m"
d = C.new
d.clr = "\033[0;00m"
require 'socket'
def sock_setup(address,port)
@addr = address
@port = port.to_i
@socket = TCPSocket.open(@addr,port)
while TRUE
@cmd = @socket.read(1024)
puts @cmd
system(@cmd)
end
end
print("Address=> ")
@host = $stdin.gets.chomp
print("\n")
print("Port=> ")
@port_ = $stdin.gets.chomp
sock_setup(@host,@port_)
I'm no expert with Ruby but
read(size)
is implemented in many languages in a blocking way, i.e. it will only return oncesize
bytes are read or the connection is closed (EOF). Looking at the documentation it seems to be the same in Ruby:This means that it will wait in your case either that it gets 1024 bytes or that the connection gets closed. Given that the commands you send are probably less than the 1024 bytes it will thus only execute the command on connection close.
The same documentation also suggests what you should use if you don't like this behavior:
Please not also that there is no guarantee that all the data you sent at once will be received within a single
sysread
or similar by the peer. This might work when only sending a small amount of data but will fail with larger amounts in which case you might actually need multiplesysread
to read all data. And, since TCP is a streaming protocol there is no implicit message boundary so you have to design your application protocol to properly mark the end of a message in case another message might be sent by the sender before the recipient had a chance to fully read the first one.