I made a simple Networking application that is server client that communicate over LAN.
client
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 8080
s.connect(("117.219.195.10", port))
s.send('q\n');
s.send('boo\n\r');
s.close
server
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
print host
port = 8080
s.bind(("", port))
s.listen(5)
while True:
c, addr = s.accept()
print 'Got connection from', addr
c.send('Thank you for connecting\r\n')
c.close()
but while server is behind NAT i need to configure the NAT table in router, Can i have a point to point connection without configuring router? Can i embed the information of NAT table (like on which ip to redirect) in the packet itself so that when packet comes form internet to router it knows which ip in the LAN should get it.
It is possible to develop an application that utilizes NAT Traversal techniques such as STUN to create a tunnel between NAT'd devices. Review those topics to find a solution that works for you.
Yes you do need to configure port forwarding and this usually involves logging on to your router and using it's administration interface. No you cannot embed this info in the packets.
However you only need to do this on your server and you do not need to resort to NAT traversal for client-server comms once port forwarding is setup on your server, since what the client sends the server will get through to the server (because you set up port forwarding) a reply from the server to client will automatically be forwarded by your client side NAT as it will be aware you have a TCP connection established to the servers' end point. That is how you can connect to this website from behind NAT!
Related
I learned to write a client and server application and how to connect them. The server host has to forward a port in the router to be able to a establish a connection.
Is it possible to connect two devices in the same network without port forwarding/triggering?
The server host has to forward a port in the router to be able to establish a connection.
You have this back to front. The router has to forward a port to the server host in order for clients outside the router to be able to form connections.
Clients inside the router, i.e. in the same subnet as the server host, can connect directly.
Yes as long as the devices are in the same network, no port forwarding is required.
Whenever a server is inside a NAT and you try to access it from outside, you have to configure port forwarding in your router.
Example:
You create a server running on port 8080 with IP 192.168.1.12
Suppose your router's public IP is 10.2.2.5
So you need to enable port forwarding in your router for port 8080 to 192.168.1.12:8080
Then you can access that server from outside with 10.2.2.5:8080
I'm trying to build a peer-to-peer game, where each player is both a server and a client with tcp sockets. The sockets can connect fine when I'm using local ip:s, but of course fails when I'm trying to use external ip:s.
But I'm thinking that the players should be able to connect to each other if they just knew the external address + port that the router assigns to them.
Setting up port forwarding is out if the question since I don't have access to the players routers.
I'm thinking of having a server in between, just to be able to read the external address and port of the players, and tell the other player about it so that it can connect.
But I haven't found any info anywhere if that's how port forwarding works. If computer A makes a request from a local address and a port to the server, and the router assigns this address + port to an external address + port, and the server tell computer B which address + port to use. Can computer B use that external address + port to connect to the computer A and start a tcp socket with it? Is there any way to know that this external address + port stays the same when another computer makes a request against them?
The problem is that most people don't expose their PC directly to the internet. They have a router that has an external address. When you send a packet to their IP address, it is going to their router. The router doesn't know where to forward it to and what port to use without port forwarding.
So, getting everyone to enable port forwarding is out of the question, as it should be. A simpler mechanism is to have a server on the internet that you control. It has a firewall with port forwarding setup. The clients are just clients, they connect to the server on a port and send and receive info about the current status of the game. That way, everyone has real-time updates on their local game engine. Plus, this way is much easier to program and implement.
No, TCP doesn't work like that.
The source port that has been used to talk to the rendezvous server will be transient and specific to that particular initial TCP socket connection and can only be used as a destination for return traffic on the same connection from the rendezvous server, and can't be used by a third party to make new inbound connections.
The typical (only?) practical solution when NATs are involved and port forwarding is not available is to have that central server relay all messages bidirectionally between the peers.
Hole punching is what I was looking for.
https://en.wikipedia.org/wiki/Hole_punching_(networking)
Problem
Following LuaSocket Introduction I managed to get the server running. I also managed to connect from the client side. But to get this connection the client must know the server port number. In the example code the server port is 0, which means:
If port is 0, the system automatically chooses an ephemeral port.
I guess this approach has it's advantages, but how does the poor client is supposed to know which port to connect to?
Question
How to communicate an ephemeral port number from server to client? I assume there should be no human action in the process.
Code
server (from LuaSocket Introduction)
-- 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
while 1 do
-- wait for a connection from any client
local client = server:accept()
-- make sure we don't block waiting for this client's line
client:settimeout(10)
-- receive the line
local line, err = client:receive()
-- if there was no error, send it back to the client
if not err then client:send(line .. "\n") end
-- done with client, close the object
client:close()
end
client (follows this answer)
local host, port = "127.0.0.1", 100
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)
if status == "closed" then break end
end
tcp:close()
How to communicate an ephemeral port number from server to client? I assume there should be no human action in the process.I assume there should be no human action in the process.
You are right. The server example is quite odd. The servers generally should bind to specific port. It shouldn't be ephemeral. So that when the server restarts the client connects to the same port as earlier. Otherwise, the clients would be at loss if server ports keeps changing.
Clients, can indeed bind to ephemeral ports ( they generally do ). Servers should be bound to specific ones.
In TCP/IP connections the server always BIND to a known port. A server is not allowed to bind to port 0. It has to be available on a known port so clients can connect to it. You should change the example to bind the server to a fixed port and then use that fixed port in the client connect function.
What I am asking is if two computers listen to the same port and a packet of information enters the router through the WAN Ip and the same port. Would the packet go to both computers? Neither? One or the other?
IE
computer 1 -(internal IP)-> 192.168.1.3 -(listens to port)-> 4444
computer 2 -(internal IP)-> 192.168.1.2 -(listens to port)-> 4444
computer 3 -(connects and sends)-> 24.157.358.45:4444
packet -> computer 1 AND computer 2
The code in VB6 is:
LAN.LocalPort = 4444
LAN.Protocol = sckTCPProtocol
LAN.Listen
I am using a WinSock object in the Microsoft WinSock Control 6.0 in VB6 Professional
If there is something that needs to be clarified I would be more than happy to.
The router won't send an inbound packet to either machine unless communication has already been established.
If 192.168.1.3 calls out to some other machine (e.g. 4.5.6.7) from its port 4444, the router will assign an arbitrary port on its external address (say 24.157.358.45 [sic] :5555) and pass the packets on to 4.5.6.7. 4.5.6.7 will send reply packets to 24.157.358.45:5555 -- because that's the only address it knows about -- and the router will relay those to 192.168.1.3:4444.
That's the normal course of things, but there are a lot of additional details to this scheme that make it possible to establish communication with a machine behind a router via trickery.
The system of having machines with private IP addresses behind a router with a public address is called network address translation (NAT); it's a pretty deep topic.
From my knowledge of routers, unless port forwarding is setup, the router will discard any packets sent on that port.
If port forwarding is setup, only one of the computers could be setup to receive the packets.
If the packet is an inbound request to establish a new TCP connection with a server that is running behind the router, the router must have an explicit port-forwarding rule configured, either statically in the router's configuration or dynamically via uPNP or SNMP, that tells the router where to route inbound packets on 24.157.358.45:4444 to, either to 192.168.1.2:4444 or to 192.168.1.3:4444, otherwise the packet will be discarded. So no, both of your listening servers will not see the same packet.
Once a TCP connection is established, the router knows which specific LAN machines are associated with which connections and will route incoming packets belonging to those connections accordingly.
The previous answers are correct, you need to enable port forwarding. If it is not enabled port 4444 will be closed on the router.
It sounds like you have multiple servers and want to forward to whatever server is turned on at the moment. This is not possible (*), the router does not care whether or not PC1 or PC2 are listening on port 4444, it will simply forward everything to the address configured in the port forwarding.
(*): Ok it is possible but it takes some extra work.
Solution 1: Trick the router into thinking there is only one server. Give PC1 and PC2 a virtual network interface with the same IP address and forward to that address. Make sure only one of these interfaces is enabled, having duplicate IP addresses in your network can have unintentional behaviour.
Solution 2: Make the router care about which server is on. You will need to write a program to run on the router (or on another server) that can detect which server is on and forward the packets accordingly. If you are using Linux the program iptables can be worth looking at.
When TCP client requests conn'n on server's listening port, server will accept it and create a new port meant for this conn'n with this client. Hence forth the client will communicate with server on this new port.
if the above statement is true and possible, how server conveys the newly generated port to client. In reply to the conn'n request the packet from server to client will have what port as source port (Server's listening port OR New port generated by server for client).
Will Client accept this port and take into use or it will give error ? I need this to implement an architecture having 2 clients and one server in an embedded system using lwip stack.
regards,
ED
The server doesn't create a new port. It creates a new TCP connection and it sends its reply packets to the IP and port the client sent its connection request from. (A TCP connection has an IP address and port on each side.)
When you connect to a server, you get a port number yourself, which is assigned to you by the system (unless you bind the socket before connecting). When the network stack of the server replies to your connection request, the "source" port is the new port number of the server, and the "destination" port of the message is your port. That's how the network stack on the client side knows what port the server has.
The new port number on the server used for your connection can not be set or changed by the actual server program, it's the network stack on the server machine that just grabs an available port number.
Edit: You might also want to read up a little on how connections are established, a.k.a. the three-way handshake.