Page 1 of 1

Hosting a UDP server in threads?

Posted: Sat Mar 11, 2017 4:48 pm
by Rucoon
I am trying to speed up a UDP game server by using threads to send the data out instead of the server, the hope is with a few threads this will work. But when I try to send data from the thread sever I am getting a "refused" error and I don't know what is causing it as it is set up the same way as the main server.

The main server file:

Code: Select all

function love.load()

	socket = require("socket")
	udp = socket.udp()
	udp:settimeout(0)
	udp:setsockname('*', 12345)

	err			= love.thread.getChannel("err")
	sendlist	= love.thread.getChannel("sendlist")
	thread1		= love.thread.newThread("thread.lua")
	thread1:start()
	
	users = {}
	
end

function love.update()

	data, ip, port = udp:receivefrom()
	if data then
		kind, name = data:match("(%S*) (%S*)")
		
		if kind == "connect" then
		
			u = {
				name	= name,
				ip		= ip,
				port	= port,
			}
			table.insert(users, u)
		
		elseif kind == "disconnect" then
		
			for i,v in pairs(users) do
				if v.name == name and
				v.ip == ip and
				v.port == port then
					table.remove(users, i)
				end
			end
		
		else
		
			for i,v in pairs(users) do
				--if v.name ~= name then
					data = string.gsub(data, " ", ";")
					sendlist:push(string.format("%s %s %s", data, v.ip, v.port))
				--end
			end
		
		end
		
	end

end

function love.draw()

	love.graphics.print(tostring(thread1:isRunning()))
	
	data = err:pop()
	if data then
		if data then
			e1, e2 = data:match("(%S*) (%S*)")
		end
		love.graphics.print(tostring(e1.." "..e2), 0, 15)
	end
	
end
The thread server:

Code: Select all

socket = require("socket")
udp = socket.udp()
udp:settimeout(0)
udp:setsockname('*', 12345)

err			= love.thread.getChannel("err")
sendlist	= love.thread.getChannel("sendlist")

while true do
	
	data = sendlist:pop()
	if data then
		data, ip, port = data:match("(%S*) (%S*) (%S*)")
		data = string.gsub(data, " ", ";")
		
		e1, e2 = udp:sendto(data, ip, port)
		err:push(string.format("%s %s", e1, e2))
	end
	
end
And the client:

Code: Select all

function love.load()

	math.randomseed(os.time())

	socket = require("socket")
	udp = socket.udp()
	udp:settimeout(0)
	udp:setpeername("localhost", 12345)
	
	name = math.random()
	udp:send(string.format("%s %s", "connect", name))

end

function love.update()

	udp:send(string.format("%s %s %s", "update", name, "Hello,world!"))
	
	data = udp:receive()
	if data then
		kind, name = data:match("(%S*) (%S*)")
		
		if kind == "update" then
			kind, name, d = data:match("(%S*) (%S*) (%S*)")
		end
		
	end
	
end

function love.draw()

	love.graphics.print(tostring(d))

end

function love.quit()

	udp:send(string.format("%s %s", "disconnect", name))
	
end
All the client is trying to do is send data to the server and then have it sent back. When the server gets the data it sends it in a channel to the thread which then is meant to send it back to the client. Thank you for any help! :D

Re: Hosting a UDP server in threads?

Posted: Sat Mar 11, 2017 7:06 pm
by Lucyy
I've created my own server / client just now, and it seems to work without any kind of problems without using threads. I've attached my files to this post for you to see.

The server doesn't use love, so you can run it with only lua (cmd: lua Server.lua), the client does use love however.

If you press space in the client, it'll send a message to the server, which the server will then send back to the client.

Re: Hosting a UDP server in threads?

Posted: Sat Mar 11, 2017 7:27 pm
by Rucoon
Lucyy wrote: Sat Mar 11, 2017 7:06 pm I've created my own server / client just now, and it seems to work without any kind of problems without using threads. I've attached my files to this post for you to see. -snip-
I can get the server working fine without threads (You can even copy the text from the thread file into the server and remove all thread and channel commands) but in my full game it is too slow when more then one player is moving. The idea was to have more then one thread going to speed things up.

Edit:
Seems that changing this in the server

Code: Select all

udp:setsockname('*', 12345)
To

Code: Select all

udp:setsockname("localhost", 12345)
Stops the refused error and instead gives "12 nil" but I still don't get any data in the client.

Edit2:
Seems to be fully working with one thread here is the code for anyone looking at this.