Having trouble using "sendto" in the lua sockets library - sockets

So I am trying to get a peer2peer matchmaking server going and I am having troubles with "sendto". I had some success with using "send" but then I couldn't do the hole punching step when the time came because it wouldn't switch peers to the other client for some reason. So now I am trying "sendto" but sendto cannot even send a message to the server.
Here is my code:
CLIENT:
local socket = require("socket")
local udp = socket.udp()
udp:setsockname("*", 0)
udp:settimeout(0)
--For server_ip I have also tried "localhost", "192.168.1.3", "127.0.0.1", and "127.0.0.0"
--none of them work. :(
local server_ip, server_port = "24.159.10.150", 30672
udp:sendto("FOO", server_ip, server_port)`
SERVER:
local socket = require("socket")
local udp = socket.udp()
udp:setsockname('*', 30672)
udp:settimeout(0)
while true do
local data, ip, port = udp:receivefrom()
if data ~= nil then
break;
end
end
print("SUCCESS!!")

Related

Unable to establish connection to a tcp socket server on aws ec2

I am trying to run a socket server on an aws ec2 ubuntu instance and then connecting with it using my local machine. I was successful with sending HTTP GET requests to my server hosted on aws ec2 instance and getting a response, but I am unable to connect the server and client using sockets, even after enabling custom TCP on the complete range of ports on the instance.
Here is a screenshot describing my instance's inbound and outbound rules :
screenshot
I used this python code from the internet to test socket networking :
socket_client.py :
import socket
def client_program():
host = "<aws instance public ip address>"
port = 8080 # socket server port number
client_socket = socket.socket() # instantiate
client_socket.connect((host, port)) # connect to the server
message = input(" -> ") # take input
while message.lower().strip() != 'bye':
client_socket.send(message.encode()) # send message
data = client_socket.recv(1024).decode() # receive response
print('Received from server: ' + data) # show in terminal
message = input(" -> ") # again take input
client_socket.close() # close the connection
if __name__ == '__main__':
client_program()
socket_server.py :
import socket
def server_program():
host = "0.0.0.0"
port = 8080 # initiate port no above 1024
server_socket = socket.socket() # get instance
# look closely. The bind() function takes tuple as argument
server_socket.bind((host, port)) # bind host address and port together
# configure how many client the server can listen simultaneously
server_socket.listen(2)
conn, address = server_socket.accept() # accept new connection
print("Connection from: " + str(address))
while True:
# receive data stream. it won't accept data packet greater than 1024 bytes
data = conn.recv(1024).decode()
if not data:
# if data is not received break
break
print("from connected user: " + str(data))
data = input(' -> ')
conn.send(data.encode()) # send data to the client
conn.close() # close the connection
if __name__ == '__main__':
server_program()
Note that the socket server-client are working completely fine when run on my local machine.
Please help if you know about how to fix this .
Edit - I have also tried with disabling firewall on the linux ec2 instance, but the problem still persists.
Thanks.

How do game clients receive UDP data from server?

What I wanted to do:
For learning about game programming I created an echo setup using a dedicated server and UDP. The dedicated server is in a different city (aka NOT in my local network).
On my local computer I have a udp client and server ( 2 different programs ). When I first started my python server I was immediately asked by windows firewall whether I want to add an exception. After allowing networking for my python server, I still did not receive any messages. (client -> dedicated server -/-> local server )
Only after I set a port forwarding in my router I was able to receive messages on my local UDP server.
My question is:
How do games solve that problem ? I don't activate a port forwarding for each multiplayer game I want to play and I'm still able to receive data in all these games.
My dedicated server setup (address and port intentionally changed):
#!/usr/bin/python3
import socket
ADDRESS = "1.123.123.123"
PORT = 12345
serverSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
serverSock.bind((ADDRESS, PORT))
clientSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addresses = []
while True:
data, addr = serverSock.recvfrom(1024)
if addr not in addresses:
addresses.append(addr)
msg = str(data)
#if msg.split()
print("Message: " + str(data))
outMsg = str(addr) + ":" + msg
for ad in addresses:
print("Send Msg " + outMsg + " to " + ad[0] + ":" + str(PORT))
clientSock.sendto(bytes(outMsg, "utf-8"), (ad[0], 12345))
print("Addresses: " + str(addresses))
I figured this one out while writing up the question (like talking to the good old rubber duck):
The trick is not using 2 programs on the local computer. The program that sends the message also needs to retrieve the message. In my example it's blocking calls (ugly!), for a game you'd want to make that asynchronous. But this is the simplest way to get around the router firewall:
#! /usr/bin/python3
import socket
ADDRESS = "1.123.123.123"
PORT = 12345
clientSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# usually not required to bind a client, but we want to receive messages
clientSock.bind(("0.0.0.0",PORT))
while True:
msg = input("Enter message: ")
# Note that it is not required to send to the same port
# you have locally binded to.
clientSock.sendto(bytes(msg, "utf-8"), (ADDRESS, PORT))
# listen to the echo:
data, addr = clientSock.recvfrom(1024)
print(str(data) + " from " + str(addr))
However, my understanding on sockets and firewalls is limited. I do not understand why THIS works but 2 separated programs don't. Maybe someone could comment on that.
Hope I can save someone some time =)

Lua Server Client Chat Example

I am trying to create a simple chat application with lua following are my files
-- load namespace
local socket = require("socket")
-- create a TCP socket and bind it to the local host, at any port
local server = assert(socket.bind("*", 0))
-- find out which port the OS chose for us
local ip, port = server:getsockname()
-- print a message informing what's up
print("Please telnet to localhost on port " .. port)
print("After connecting, you have 10s to enter a line to be echoed")
-- loop forever waiting for clients
local client = server:accept()
client:setoption("keepalive", true)
while 1 do
local line, err = client:receive()
print(line .. 'sent by client')
if not err then
client:send(line .. "\n")
else
print('error')
print(err)
end
end
client:close()
server.lua
local host, port = "127.0.0.1",arg[1]
local socket = require("socket")
local tcp = assert(socket.tcp())
tcp:connect(host, port);
--note the newline below
tcp:send("hello world\n");
while true do
local s, status, partial = tcp:receive()
print(s or partial)
print("enter message to send")
local message = io.read()
print("sending message" .. message)
tcp:send(message);
if status == "closed" then break end
end
tcp:close()
client.lua
Now I cannot get my head around that the server does not receive after the first hello world and how do i connect another client while the server is already connected to the client, does lua offer any callback for receive or connection established?
You never send any actual end of line to the server, after the first line. Since message will not contain any line end, client:receive() will wait for the end forever (because it reads a line from the socket).
You can try calling server:accept() multiple times to wait for a new client. Combined with a timeout and coroutines, you can serve multiple clients.

Trouble with Lua TCP server when using loop to receive and send messages multiple times

I need a client and server to communicate through a socket. The client tells the server that it wants a specific message (through a string "arquivo") and gets the message that is supposed to be 10KB long. Both of them have to maintain the connection open in case the client wants to ask for the message again with that same string. I could implement that for 1 exchange, closing the connection. When I put in a while though, the server apparently sends the message but it never gets to the client, unless I close the terminal window where the client is running. I ran each in a separate terminal window and tested the client's code with a server that only transmits the message once and then closes the connection and the message came through. The problematic server code is as follows:
filename = "file10KB.txt"
file = assert(io.open(filename, "r"))
msg = file:read("*a")
file:close()
socket = require("socket")
host = "*"
port = 8080
print("Binding to host '" .. host .. "' and port " .. port .. "...")
server = assert(socket.bind(host, port))
server:setoption("reuseaddr", true)
ipaddress, socketport = server:getsockname()
assert(ipaddress, socketport)
print("Waiting connection from client on " .. ipaddress .. ":" .. socketport .. "...")
connection = assert(server:accept())
connection:setoption("keepalive", true)
connection:settimeout(10)
print("Connected!")
while true do
print("Waiting for request...")
data, errormsg = connection:receive()
if data == "arquivo" then
print("Proper request received, sending message...")
assert(connection:send(msg .. "\n"))
print("Message sent!")
elseif not errormsg then
print("Invalid request.")
break
else
print("Error message: " .. errormsg)
break
end
end
Also, my client's code:
socket = require("socket")
host = "localhost"
port = 8080
print("Attempting connection to server '" .. host .. "' and port " .. port .. "...")
client = assert(socket.connect(host, port))
client:setoption("keepalive", true)
client:setoption("reuseaddr", true)
client:settimeout(10)
print("Connected!")
repeat
print("Sending message request...")
assert(client:send("arquivo" .. "\n"))
print("Message request sent! Waiting for message...")
data, errormsg = client:receive("*a")
if data then
print("Message received!")
print(data)
else
print("Failed to receive message.")
break
end
until not client
I'm new to Lua and to sockets and I followed some tutorials I found on the web, such as http://www.portugal-a-programar.pt/topic/36175-aprendendo-a-usar-lua-socket/ (it's in portuguese). I just hope any of you could shed a light on what I'm missing. I'm using Mac OS X machine by the way, don't know if that's any helpful.
When I put in a while though, the server apparently sends the message but it never gets to the client, unless I close the terminal window where the client is running
I don't know what this means. Closing the terminal window should close the client, which hardly means it will suddenly receive a message.
However there are numerous problems with this, too long for comments:
You need to set SO_REUSEADDR before binding. Afterwards is too late.
You don't need to set it at the client at all, but if you do it must be before connecting.
The sockname check in the server is pointless. It can't fail.
Your server only accepts one connection.
Your server never closes the connection.
Your server doesn't appear to recognized end of stream correctly.
Your client never closes the connection.
The problem was in the
data, errormsg = client:receive("*a")
line in the client's code. The option *a only receives when the connection is closed and changing it to *l or nothing like below made it work.
data, errormsg = client:receive()

Recover a TCP connection

I have a simple Python server which can handle multiple clients:
import select
import socket
import sys
host = ''
port = 50000
backlog = 5
size = 1024
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host,port))
server.listen(backlog)
input = [server,sys.stdin]
running = 1
while running:
inputready,outputready,exceptready = select.select(input,[],[])
for s in inputready:
if s == server:
# handle the server socket
client, address = server.accept()
input.append(client)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
else:
# handle all other sockets
data = s.recv(size)
if data:
s.send(data)
else:
s.close()
input.remove(s)
server.close()
One client connects to it and they can communicate. I have a third box from where I am sending a RST signal to the server (using Scapy). The TCP state diagram does not say if an endpoint is supposed to try to recover a connection when it sees a RESET. Is there any way I can force the server to recover the connection? (I want it to send back a SYN so that it gets connected to the third client)
Your question doesn't make much sense. TCP just doesn't work like that.
Re "The TCP state diagram does not say if an endpoint is supposed to try to recover a connection when it sees a RESET": RFC 793 #3.4 explicitly says "If the receiver was in any other state [than LISTEN or SYN-RECEIVED], it aborts the connection and advises the user and goes to the CLOSED state.".
An RST won't disturb a connection unless it arrives over that connection. I guess you could plausibly forge one, but you would have to know the current TCP sequence number, and you can't get that from within either of the peers, let alone a third host.
If you succeeded somehow, the connection would then be dead, finished, kaput. Can't see the point of that either.
I can't attach any meaning to your requirement for the server to send a SYN to the third host, in response to an RST from the third host, that has been made to appear as though it came from the second host. TCP just doesn't work anything like this either.
If you want the server to connect to the third host it will just have to call connect() like everybody else. In which case it becomes a client, of course.