Writing binary to a socket..

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
CaptainMaelstrom
Party member
Posts: 161
Joined: Sat Jan 05, 2013 10:38 pm

Writing binary to a socket..

Post 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.
User avatar
Plu
Inner party member
Posts: 722
Joined: Fri Mar 15, 2013 9:36 pm

Re: Writing binary to a socket..

Post 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
Last edited by Plu on Tue Oct 15, 2013 7:06 am, edited 1 time in total.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Writing binary to a socket..

Post 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.
Help us help you: attach a .love.
User avatar
Plu
Inner party member
Posts: 722
Joined: Fri Mar 15, 2013 9:36 pm

Re: Writing binary to a socket..

Post 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)
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Writing binary to a socket..

Post 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
Shallow indentations.
User avatar
CaptainMaelstrom
Party member
Posts: 161
Joined: Sat Jan 05, 2013 10:38 pm

Re: Writing binary to a socket..

Post 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?
User avatar
CaptainMaelstrom
Party member
Posts: 161
Joined: Sat Jan 05, 2013 10:38 pm

Re: Writing binary to a socket..

Post 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?
Attachments
clientTest.love
(2.93 KiB) Downloaded 353 times
serverTest.love
(3.04 KiB) Downloaded 340 times
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Writing binary to a socket..

Post 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.
Shallow indentations.
User avatar
CaptainMaelstrom
Party member
Posts: 161
Joined: Sat Jan 05, 2013 10:38 pm

Re: Writing binary to a socket..

Post 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.
Attachments
clientTest.love
(3.06 KiB) Downloaded 330 times
serverTest.love
(3.08 KiB) Downloaded 348 times
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Writing binary to a socket..

Post 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.
Shallow indentations.
Post Reply

Who is online

Users browsing this forum: pgimeno and 168 guests