How to host twisted python code to the Internet? - server

Currently I Have This Following Code Which Simply Echo's The Data Which Is Sent To The Server and Shows The Number Of Active Connections In The Server To The Clients and Sends Some Info.
from twisted.internet.protocol import Protocol , Factory
from twisted.internet import reactor
from twisted.internet.endpoints import TCP4ServerEndpoint
connections = -1
class echo_simple(Protocol):
def connectionMade(self):
global connections
connections += 1
self.transport.write(f'Number of active connections in the server are: {connections} '.encode('utf-8'))
def connectionLost(self,*args , **kwargs):
global connections
connections -= 1
print(':: N :: A Connection Just Closed :: N ::')
def dataReceived(self, data):
data = data.decode('utf-8')
print(f':C: {data} ')
self.transport.write("\n Server Successfully Received Your Message!".encode('utf-8'))
self.transport.write(f"\n |THE MESSAGE YOU SENT IS : {data}|".encode('utf-8'))
self.transport.write(f'\n Closing The Connection As This is Just An Echo Server'.encode('utf-8'))
self.transport.loseConnection()
class Server_factory(Factory):
def buildProtocol(self, addr):
print(" |^INFO^| Created An Instance ")
return echo_simple()
endpoint = TCP4ServerEndpoint(reactor, 8009)
endpoint.listen(Server_factory())
reactor.run()
My Problem Is The Server Is Currently Listening In The LocalHost , I want to host this in the internet globally !
Say for example i have an domain called www.examplecode.com
Instead of listening in the localhost , how to change my code so that it listens to the www.examplecode.com instead of localhost ?

You need the domain to point to a server, that runs this code.
When you buy the domain, the registrar you buy it from usually gives you an interface to setup the dns configuration, usually you'll setup an AA or CNAME record to point to the ip or existing other domain that points to the server you will use to run the code.
You will usually rent a server from another company (there are plenty of them), that will run in a data center and will be taken care of, connect to that server, and deploy your code on it (often through ssh), and make it listen on 0.0.0.0 so it accepts connections from anywhere. You then get the IP of this server, and use it to setup the DNS in the interface provided by your registrar.
Alternatively, you can use a computer at your home, if you configure your router to direct connections on the 440 and 80 port to the local ip of this PC, and you put the ip of your home connection in the registrar DNS configuration (hopefully you have a static ip though).
Anyway, it's a bit of a wide subject for a stackoverflow question (and it might not even be on topic for stackoverflow, maybe it's more a serverfault question, or a superuser, one.

Related

Using UDP between remote server and client

I am currently working on a project that needs a UDP communication between a server Amazon Frankfurt) and several hosts (Arduino). I need to be able to send JSON data from server to a host over UDP and it needs to work in real time (time is a real constraint here). Also, periodically a host will speak to server to inform server about its status.
The problem I'm facing is that although I can ping the server, when I create the UDP socket with a port, I get this error (for any port):
errno99: cannot assign requested address
I also believe that since the hosts are in different countries, I can only get router's IP. Hosts will be given to users therefore it is impossible to alter user's router by hand. I need to use something that can handle these by code.
I have been searching on Hole Punching and other techniques. I cannot decide what suits more to my scenario here. Sorry for my lack of network information, any help or guidance as "read or search these techniques" are appreciated.
This code runs on server:
import socket
import time
#Host's public IP
UDP_IP_ADDRESS = "178.243.98.86"
UDP_PORT_NO = 13000
Destination = (UDP_IP_ADDRESS,UDP_PORT_NO)
Message = "Hello, Server"
senderSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
senderSock.sendto(Message, Destination)
time.sleep(1);
And this code runs on my machine:
import socket
#Server's public IP
UDP_IP_ADDRESS = "172.31.46.111"
UDP_PORT_NO = 13000
recieverSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
recieverSock.bind((UDP_IP_ADDRESS, UDP_PORT_NO))
while True:
data, addr = recieverSock.recvfrom(1024)
print "Message: ", data
Server
# Host's public IP
UDP_IP_ADDRESS = "178.243.98.86"
You cannot rely on 178.243.98.86. Your arduinos are behind one or several NATs. With NAT, when a packet leaves a network, your packets source and/or destination addresses (and most likely ports) get rewritten. When this conversion happens, a device responsible for NAT remembers this conversion, but only for a limited period of time. The period usually defaults to 24h.
In order to overcome this issue, it's up to clients to initiate conversations with the server. Introduce a new message type to your protocol saying something like hey it's me, client #34. The server should be associating source IP and port of the received message with client #34 for some period of time, like hours.
In this case the server binds a socket to an address and port as well as a client. And beware that hey it's me, client #34 sent over UDP is not encrypted and is extremely vulnerable to record and replay attacks. I believe an emergency system should be encrypted.
Client
# Server's public IP
UDP_IP_ADDRESS = "172.31.46.111"
172.31.46.111 cannot be server's public IP, because it is an address from an IPv4 private space. You probably meant to say "host's private address". It makes sense to bind to such an address. You get an error most likely because you have incorrectly determined the IP address of your host.
There are several ways to get the correct IP. If you use DHCP (you use it if you've never though about what IPs to use in your SOHO), log into your nearest router's admin interface and check the DCHP Pool. Alternatively, Linux and Windows have terminal commands to do the same. For Arduino, you have probably assigned it a static address. If so, bind to it.
You also seem to open a tcp socket on the server, and connect to it from client via udp socket. Is this intentional?
gsn

How does the computer know what port is a packet for?

Let's assume I'm in computer A, I have a few servers running on different ports, but all are basically an instance of the same program (just binding to different ports). Now, computer B, a client, does he need to know what port is the software he wishes to connect to on computer A?
The point is, I am implementing some sort of communication similar to sockets. Everything should work fine but I'm not sure how to create the initial-message from a computer to another - I just don't know to what port to send it to. Does the client know the port he's sending to on the server?
Say here (client): clientsocket.connect(('localhost', 8089)), does the client connect a server running on port 8089? If so, what port is his socket on (what port is he using for the client?
Yes. The only way for the network stack on computer A to know which process to deliver an incoming packet is for computer B to set the correct port in the packet. A web server runs on port 80 by default, but a machine running several distinct web servers will run them on distinct ports, and a client must be specific about which server they want to connect to. http://example.com, http://example.com:8080, and http://example.com:12345 would refer to the servers running on example.com on ports 80, 8080, and 12345, respectively.
In order to know which port to use in your client, you need to read the documentation for the server you want to connect to.
Going in the other direction, the port used by the client to receive responses is typically set by the networking stack automatically. The client doesn't need to do anything special to set it, and the server simply sends packets back to the address/port found in the source portion of the incoming packet.

How Can I ping or create a scoket connection with my friend?

When we ping to any Public IP of a router it give a reply,
we dont get reply, if we ping a local computer with its private IP of a particular network,
So is there a way so I can make direct connection or socket with a particular PC in a network.
I have heard that, I have to make connection with public IP of a particular network and the port number will decide, on which PC in that network , my request will go.
But this method is not working..
If the computer is behind a router that uses Network Address Translation (NAT) - that is, the computer has a private IP that is not visible to the internet - then you cannot ping or establish a connection to the computer from the outside. This is because the router does not know which computer you want since all the computers behind the router share the same public IP address.
The way to establish a connection in this case is to have the computer which is behind the router establish the connection to the outside computer. For example, when you go to a web site, you can do it from a computer behind a router since your computer is initiating the connection. However, the web server you are going to must have a public IP.
When a computer behind the router initiates a connection, the router does select a port number to associate with that connection so packets from the outside for that connection will go to the right computer. However, this only works for traffic on that particular connection; the port number is not a general purpose mapping to that computer.
Two computers behind the same router can establish connections with each other using the private IPs as they don't have to go through the router to do it.
You can decide with your friend who is going to be the client (the one initiation the TCP connection) and who is the server (the one receiving the TCP connection) and which port should be used (let's say X). Let's say that your friend is the server. Then he/she has to configure his/her router to redirect all the traffic to the router to port X to his/her private IP to port X (this is what Warren mentioned as NAT).
If you use a port above 1024, the server (running on your friend's PC) doesn't need root/administrator privileges.
Your program (the client) would then connect to the public IP address of your friend. He/she can check his/her public IP with: What is my IP

How to create a socket connection over nat from public end

I feel this question is best started with a simplified version of the scenario.
Server A is connected to the public internet.
Server B is in a private Network and uses network address translation to connect to the internet.
I own both servers and can edit the software on them.
The ip addresses of the servers and the nat router are known to me.
Using Winsock, I need to create a connection between them. I know enough about winsock for this to be trivial if the connection is started from server B, but I need server A to start the connection.
I want to avoid using additional libraries if possible as it would appear to me that I only need to figure out what ip and port server A needs to use when starting the connection.
What additional information do I require, How do I acquire it, and How do I act upon the information.
note: I have investigated other similar questions, but none of them addressed this situation. I am not sure if this should have been asked on server fault or another site, but if so please say which one before flagging as "off topic" instead of closing the question wordlessly.
You need to setup port forwarding on the NAT device to the machine on the private network. Exact steps are device/manufacturer-specific, but here's the general idea:
Pick a port number, configure the NAT device so that connections to its public IP and that port are forwarded to the IP of your private server and the port where your application is listening.

What does it mean to connect to a certain port?

For example, when you make an ssh connection, you are connected to port 22. What happens then? On a very high level brief overview, I know that if port 22 is open on the other end and if you can authenticate to it as a certain user, then you get a shell on that machine.
But I don't understand how ports tie into this model of services and connections to different services from remote machines? Why is there a need for so many specific ports running specific services? And what exactly happens when you try to connect to a port?
I hope this question isn't too confusing due to my naive understanding. Thanks.
Imagine your server as a house with 65536 doors. If you want to visit family "HTTP", you go to door 80. If you were to visit family "SMTP", you would visit door no. 25.
Technically, a port is just one of multiple possible endpoints for outgoing/incomming connections. Many of the port numbers are assigned to certain services by convention.
Opening/establishing a connection means (when the transport protocol is TCP, which are most of the “classical” services like HTTP, SMTP, etc.) that you are performing a TCP handshake. With UDP (used for things like streaming and VoIP), there's no handshake.
Unless you want to understand the deeper voodoo of IP networks, you could just say, that's about it. Nothing overly special.
TCP-IP ports on your machine are essentially a mechanism to get messages to the right endpoints.
Each of the possible 65536 ports (16 total bits) fall under certain categories as designated by the Internet Assigned Numbers Authority (IANA).
But I don't understand how ports tie into this model of services and
connections to different services from remote machines? Why is there a
need for so many specific ports running specific services?
...
And what exactly happens when you try to connect to a port?
Think of it this way: How many applications on your computer communicate with other machines? Web browser, e-mail client, SSH client, online games, etc. Not to mention all of the stuff running under the hood.
Now think: how many physical ports do you have on your machine? Most desktop machines have one. Occasionally two or three. If a single application had to take complete control over your network interface nothing else would be able to use it! So TCP ports are a way of turning 1 connection into 65536 connections.
For example, when you make an ssh connection, you are connected to
port 22. What happens then?
Think of it like sending a package. Your SSH client in front of you needs to send information to a process running on the other machine. So you supply the destination address in the form of "user#[ip or hostname]" (so that it knows which machine on the network to send it to), and "port 22" (so it gets to the right application running on the machine). Your application then packs up a TCP parcel and stamps a destination and a return address and sends it to the network.
The network finds the destination computer and delivers the package. So now it's at the right machine, but it still needs to get to the right application. What do you think would happen if your SSH packet got delivered to an e-mail client? That's what the port number is for. It effectively tells your computer's local TCP mailman where to make the final delivery. Then the application does whatever it needs to with the data (such as verify authentication) and sends a response packet using your machine's return address. The back and forth continues as long as the connection is active.
Hope that helps. :)
The port is meant to allow applications on TCP/IP to exchange data. Each machine on the internet has one single address which is its IP. The port allows different applications on one machine to send and receive data with multiple servers on the network/internet. Common application like ftp and http servers communicate on default ports like 21 and 80 unless network administrators change those default ports for security reasons