Page 1 of 2

Creating a server using ENet

Posted: Tue Jun 07, 2016 5:36 am
by Ortimh
Hello there! Thank you for visiting my help thread.

I'm trying to create a game with multiplayer in it, but the problem is I don't have any knowledge with networking. I'm trying to create a server with ENet using external IP and random allocated port (maybe). Without any further chit-chat, let's jump to the code. I'm going to post the server only. First one is the main.lua and the second one is the thread.lua.

Code: Select all

local function split(string, delimiter)
	local strings = {}
	
	for string in string:gmatch("[^" .. delimiter .. "]+") do
		strings[#strings + 1] = string
	end
	
	return strings
end

local ip, port
local thread
local channel
local time, cancel
local host

function love.load()
	require "enet"
	
	port = select(2, unpack(split(enet.host_create():get_socket_address(), ":")))
	thread = love.thread.newThread("thread.lua")
	channel = {
		ip = love.thread.getChannel("ip_ip"),
		request = love.thread.getChannel("ip_request")
	}
	time = 0
	
	thread:start(true)
end

function love.update(dt)
	if (not ip and not cancel) then
		if (time < 5) then
			time = time + dt
			ip = channel.ip:pop()
			
			if (ip) then
				host = enet.host_create(ip .. ":" .. port)
			end
		else
			cancel = true
			
			channel.request:push(true)
		end
	end
end

function love.draw()
	love.graphics.print("IP address: " .. (ip or "unknown"), 10, 10)
	love.graphics.print("Internal port: " .. (port or "unknown"), 10, 24)
	
	if (host) then
		love.graphics.print("Server state: available", 10, 38)
	else
		love.graphics.print("Server state: unavailable", 10, 38)
	end
end

Code: Select all

local http = require "socket.http"
local channel = {
	ip = love.thread.getChannel("ip_ip"),
	request = love.thread.getChannel("ip_request")
}
local ip, cancel

repeat
	ip = http.request("http://myip.dnsomatic.com/")
	cancel = channel.request:pop()
until (ip or cancel)

if (ip) then
	channel.ip:supply(ip)
end
The problem is, when I run the code, the message always printed "Server state: unavailable" no matter how long I waited. I'm requesting a help from you. If you know anything about networking, please do me a favor! Thank you for you time that you're still reading this! :D

Re: Creating a server using ENet

Posted: Tue Jun 07, 2016 7:38 am
by Linkpy
For creating a server you don't need your IP, just use "localhost" or "127.0.0.1". Get your IP from a distant server (in this case, myip.dnsomatic.com) is only a helper. This allow you to know your internet IP, and then you can directly share it with your friends / people.

I also see that you call two time "enet.host_create()", the first time to get the socket address and parse it to get the port. For a game, it's very rare to see a server with random port (just look at TF2, or Starbound, Terraria, KF & KF2, etc). You should use the IP "127.0.0.1" and a static port. Using a random port can lead to use a specific protocol port (for example, a port used in torrent, or event for a game), and so leading to conflict with other programs.

Re: Creating a server using ENet

Posted: Tue Jun 07, 2016 8:17 am
by Ortimh
Thank you for your answer, Linkpy, but how do the clients can connect to the server? By using "localhost" again? What if I create 2 servers? How do the clients can connect to a specific server?

Re: Creating a server using ENet

Posted: Tue Jun 07, 2016 8:34 am
by bartbes
Linkpy wrote:For creating a server you don't need your IP, just use "localhost" or "127.0.0.1".
Except that is something you don't want to specify, as it binds to the loopback interface, thus making your server accessible only for the local machine. Either specify "0.0.0.0", or even better, "*".
Ortimh wrote:how do the clients can connect to the server? By using "localhost" again?
No, by specifying the ip address they can use to reach you. If they're on the same LAN, it can just be your internal ip, if they're not, you'll have to find your global ip, and make sure to set your router to forward to relevant port to your machine.

Re: Creating a server using ENet

Posted: Tue Jun 07, 2016 8:41 am
by Ortimh
Thank you, bartbes, but "what if I create 2 servers? How do the clients can connect to a specific server?" Well if that's possible.

Re: Creating a server using ENet

Posted: Tue Jun 07, 2016 8:50 am
by bartbes
Well, they have to bind to different ips or ports, so that's how you connect to a specific server. That said, it really makes no sense to run multiple servers from the same application.

Re: Creating a server using ENet

Posted: Tue Jun 07, 2016 9:22 am
by Ortimh
Thanks, bartbes, so in conclusion when you create a server, specify "0.0.0.0" or "*" for the IP and a static port (e.g. 19060) for the port? But how to get the server's IP (and port) when a client wants to connect? Sorry for this because I have limited knowledge of networking thingy.

Re: Creating a server using ENet

Posted: Tue Jun 07, 2016 10:44 am
by Linkpy
You have multiple ways to do this. If it's a little game, the IP is from a web site, or just given by the host to the played (in a forum, with Skype, etc). But, if you have a big project (like World of Tanks, War Thunder, Overwatch or even Battleborn) were servers are hosted in big infrastructures, then you will have to do a "master" server, with a static IP and port, which transmit the game server's IP and port.

But, I think, the simple way is to allow the user to set the IP and the port (for both the server and within the game connection screen), just like in Garry's mod, TF2, and many other game. In this case, you just have to define a default port, that's all.

Edit :
bartbes wrote:Except that is something you don't want to specify, as it binds to the loopback interface, thus making your server accessible only for the local machine. Either specify "0.0.0.0", or even better, "*".
I tried many time to make a server, for example using Node.JS, and I used "localhost" or "127.0.0.1" for the IP and from outside of my local network people have access to my server and I never used "0.0.0.0" or "*" as IP. Maybe you're right, but for my it's work.

Re: Creating a server using ENet

Posted: Tue Jun 07, 2016 10:52 am
by Ortimh
So in conclusion, let the player decides the IP and port?

Re: Creating a server using ENet

Posted: Tue Jun 07, 2016 12:06 pm
by Linkpy
Basically, yes. Just add a default IP for server (like "0.0.0.0", "*", "localhost", etc) and a default port for server and client (like 19060).