Page 1 of 2

Writing binary to a socket..

Posted: Tue Oct 15, 2013 1:12 am
by CaptainMaelstrom
Hey all,

I'm trying to use LOVE2D to make a GUI for a school project. I need to be able to write binary to a luasocket. I can successfully connect at this point, but when I:

Code: Select all

connection:send(5)
the receiving end gets 309. I don't think it's going to be possible for me to change how the receiver reads the data, (I think it's a camera, and it expects binary). So is there anyway I can convert a lua number to binary? I tried researching the io library, but it seems like it's only useful for writing to files. If I have to write a C function and wrap it in Lua, I guess I will. Seems like there should be an easier way.

Re: Writing binary to a socket..

Posted: Tue Oct 15, 2013 6:25 am
by Plu
I guess it would depend on how the camera expects to receive the binary number. You can store any binary sequence you want in a string and send that, it should at least give you pretty good control over what goes out. Have you openend to socket in binary mode?

You can use hexadecimal notation to send specific bytes over the line. Hexadecimal starts with 0x in front of the number and should be easy to convert to and from binary.

Code: Select all

socket.send( string.char( 0x05 ) ) -- send a byte with binary value 5

Re: Writing binary to a socket..

Posted: Tue Oct 15, 2013 7:00 am
by Robin
Plu wrote:You can use hexadecimal notation to send specific bytes over the line.
Fun fact: 0x05 is exactly the same thing in Lua as 5. If 5 does not work, neither will 0x05.

Re: Writing binary to a socket..

Posted: Tue Oct 15, 2013 7:06 am
by Plu
Uh, crap. I meant string.char( 0x05 ). That should be a binary 5-byte.

(Of course string.char( 5 ) should also work, but if you're going the binary route it's best to use binary representation)

Re: Writing binary to a socket..

Posted: Tue Oct 15, 2013 7:17 am
by Boolsheet
Sockets should always be binary. It's just a matter of how you choose to receive them that will break the binary stream apart. If you call tcp_socket:receive without arguments, it defaults to the "*l" mode which is line mode.

socket:send expects strings. Like Plu said, you have to convert the number into a string first. The representation (human readable, 4 byte long little-endian integer, ...) and how you get there is up to you.

I have no idea how you got 309 from "5" so it might be better if you show us your receiving code. :P

Re: Writing binary to a socket..

Posted: Tue Oct 15, 2013 6:34 pm
by CaptainMaelstrom
Okay, thanks you guys. I've also found this for anybody researching the same problem: http://www.giderosmobile.com/forum/disc ... lua-socket

I have a new problem though : / .

I can't get luasocket to send and receive data. I have my .love files attached, here's my client code:

Code: Select all

require "scripts/aliases"
require "scripts/helpers"
local socket = require "socket"


function love.load()
	client,clientErr = socket.tcp()
	connection,connectErr = client:connect('127.2.3.4',1234)
end

function love.update(dt)
	
end

function love.draw()
	if client then lg.print('socket created',20,5) end
	if clientErr then lg.print('client error: ' .. clientErr,20,20) end
	if connectErr then lg.print('connect error: ' .. connectErr,20,40) end
	
	if connection then lg.print('connection made',20,80) end
	if message then lg.print(message,20,100) end
end

-------------------------------

function love.keypressed(k,uc)
	if k=='r' then
		message = client:receive('*a')
	end
end
I can connect without errors, but when I press 'r', the program stops responding, and i presume it never receives data. : /
What am I doing wrong?

Re: Writing binary to a socket..

Posted: Tue Oct 15, 2013 6:34 pm
by CaptainMaelstrom
Okay, thanks you guys. I've also found this for anybody researching the same problem: http://www.giderosmobile.com/forum/disc ... lua-socket

I have a new problem though : / .

I can't get luasocket to send and receive data. I have my .love files attached, here's my client code:

Code: Select all

require "scripts/aliases"
require "scripts/helpers"
local socket = require "socket"


function love.load()
	client,clientErr = socket.tcp()
	connection,connectErr = client:connect('127.2.3.4',1234)
end

function love.update(dt)
	
end

function love.draw()
	if client then lg.print('socket created',20,5) end
	if clientErr then lg.print('client error: ' .. clientErr,20,20) end
	if connectErr then lg.print('connect error: ' .. connectErr,20,40) end
	
	if connection then lg.print('connection made',20,80) end
	if message then lg.print(message,20,100) end
end

-------------------------------

function love.keypressed(k,uc)
	if k=='r' then
		message = client:receive('*a')
	end
end
I can connect without errors, but when I press 'r', the program stops responding, and i presume it never receives data. : /
What am I doing wrong?

Re: Writing binary to a socket..

Posted: Tue Oct 15, 2013 7:21 pm
by Boolsheet
LuaSocket blocks by default; there are no timeouts. socket:receive("*a") basically means receive until connection is closed.

Use socket:settimeout to set a timeout. You can use 0, but I don't remember if there were any issues with that. You also need to check all 3 return values from the receive function if you set a timeout. The third contains the partial message.

Re: Writing binary to a socket..

Posted: Tue Oct 15, 2013 7:50 pm
by CaptainMaelstrom
Boolsheet,

I set the timeout for the client object, tried to receive data, and then close the connection from the server side, but for some reason the server won't close the connection.

Code: Select all

function love.keypressed(k,uc)
	if key=='c' then connection:close() closed = true end
end
Is this not the right way to do it?
Thanks.

Re: Writing binary to a socket..

Posted: Tue Oct 15, 2013 8:37 pm
by Boolsheet
In the server's main.lua, you check for 'key' instead of 'k' in love.keypressed. It won't execute the code that way.

You also set a timeout of 3000 seconds. That seems as good as infinity. :P

Try to do the receiving in the love.update callback in a way so that the LÖVE event handling still takes place. That means you have to create a function that can be called from love.update, checks if something was received on the socket (adds it to the table or whatever) and then quickly returns so that other stuff can update and the frame can be drawn.