socket programing cant connect to another network - python

I recently wrote a client/server pair in python using sockets,but the problem is client doesn't connect to server on another network.I've tried port forwarding and making internal IP address static, a question which really bother's me is do i need External/Public IP address to make the client connect and if this is the case what to do when the ISP changes my External IP address. Please give some suggestions,thanks.
code:
PORT=8888
srvsock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
srvsock.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
srvsock.bind( ('', PORT) )
srvsock.listen( 10 )
print 'server now listening on PORT '+str(PORT)
while 1:
clisock, (remhost, remport) = srvsock.accept()
dl_information_file="server.txt"
if os.path.exists(dl_information_file):
f=open('server.txt','rb')
read=f.read()
clisock.send( read )
f.close()

First of all, try to run both server and client from the same computer (connect to localhost)
If that works your problem is port forwarding related.
see: how to portforward

Are the client and server on a local network or is the client and server separated by the Internet?
If the server is running on a machine behind a NAT, you will have to do portforwarding on that and make sure that the machine's IP is static or that you update the client with the updated IP.
If the server is within your own network, you can use socket.gethostbyname(socket.getfqdn()) to get the IP of your interface (careful, you may have more than one) and use that IP to bind a socket.
You may also use WireShark to troubleshoot the connection - you can see what packets are making their way out of your client and what packets are making their way to your server.
Without further code and more information on the network, it's really hard to say any more - it could be the firewall, it could be the NAT, it could be a badly configured interface.
edit: It appears that you're binding the socket to '', which means it should be bound to the localhost port, meaning that the server listens for connections on the local loopback (127.0.0.1). This interface is not accessible to any other machine that the one which the server is running on.
You should use either a statically configured IP in a variable in your script, or that socket.gethostbyname(socket.getfqdn())).

Related

How can I create a TCP connection in Python between 2 PCs

So far I have made a VERY basic client/server application that creates a TCP connection. I have a lot of programming experience, just never did this low-level stuff and especially nothing with networks. Note that all the prints are just to help me figuring out what is going on. One of the known issues is that jsonip sometimes gives me an IPv4 and sometimes v6, I don't know why but that doesn't matter for now, just to warn anyone who wants to recreate my code.
Server:
import socket
import requests
port = int(input("Enter port you want to open:\n"))
#todo: add errorhandling
print("Adding socket...")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
hostname = socket.gethostname()
print(f"Hostname: {hostname}")
ip_address = socket.gethostbyname(hostname)
print(f"Host address: {ip_address}")
r = requests.get(r'http://jsonip.com')
public_ip_address = r.json()['ip']
s.bind((ip_address, port))
print("Is open for connections on IP: "+public_ip_address+" and Port: "+str(port))
s.listen(5)
print("Done initialisation, listening for incoming connections...")
while True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established")
clientsocket.send(bytes(f"You have connected to server: {hostname}", "utf-8"))
Client:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = input("Enter IP to connect to:\n")
port = int(input("Enter Port to connect to:\n"))
print(f"Connecting to server {ip} ...")
s.connect((ip, port))
msg = s.recv(1024)
print(msg.decode("utf-8"))
On my local machine: Open 20000 in my server.py, it tells me the host is 127.0.1.1, I then enter 127.0.1.1 into my client script and 20000, and they connect. So the Socket has been bound with the 127.0.1.1. (Side question: What is this IP address, is it like the internal IP address of processes in my PC or something? If running ip a on my other machine it is the first one shown of 2)
Using Virtmanager on my machine and running one Linux Server (command line only) and one normal Ubuntu, the server tells me the host is, again, 127.0.1.1 which I don't need to enter into the other VM to know it won't work, what does work however, is getting the IP-address of the Server via ip a, which in this case is 192.168.122.37, and when I enter this IP address into the client, it connects. But in the socket here I bind, again, the 127.0.1.1, so is it arbitrary what I put here? What SHOULD I bind here, the public, the weird or the 192. address?
The first thing I could not get to work was using 2 physical devices. When opening a server on my Linux machine, I cannot connect with my windows machine at all, no matter if I use my public, my 127. or my 192. IP-address. Now my end goal is doing this over the internet so I am walking myself up, describing here the steps I took to try and get where I want to be but here I hit a brick wall where I don't know what is wrong. Am I binding the wrong address on the server, is my router being a problem, is there something else wrong?
I also tried leaving my network using my friends pc a few countries over, but this also just results in a timeout (my theory is that the Router port he is trying to open is closed and I have now idea how I can make the router send data to his PC, which should be not impossible as firefox and every application using internet does it without me having to manually forward every port, I just don't know how). This is my end goal, creating a connection between my friends PC and mine, and this is how far I got (I wouldn't mind skipping the local network if it is not relevant for fixing the global connection problem), so, tl;dr: what did i do wrong, what do i need to bind and what do i need to do for the final result to work?
There are many questions to answer.
Addresses 127.X.X.X are reserved for the loopback interface, most common one is 127.0.0.1. The loopback is a virtual, but important interface and as you have probably guessed, it is usable on the local machine only. You cannot use 127.X.X.X address to make two hosts to communicate with each other.
Addresses 192.168.X.X (and also 10.X.X.X and 172.16-31.X.X.) are reserved for local LANs. They are not valid on the Internet.
You cannot use these addresses to make two hosts to communicate with each other over the public Internet (unless you create a tunnel, an advanced networking topic)
Almost everybody uses them, because we ran out of IPv4 addresses long time ago, they were difficult to get, expensive, etc. Also such hosts are isolated from the Internet, they can be reached only via a router that translates addresses. Such router feature is called NAT. A typical router has one valid Internet address and all connections to the Internet appear as coming from the router. If you contant a service like jsonip.com from a PC, you get your router's address, not your PC's address.
See also: Finding local IP addresses using Python's stdlib
To make your program working, make it to accept connections on all interfaces. See the first example in the socket docs. On Linux, use port numbers >= 1024. Ports < 1024 are reserved, not available to regular users.
Final point is that a firewall may prevent connections to your server. It depends on your system and setup.

Python sockets google dns server

I need my own IP in a small script and in order not to hardcode it, I`ve found a piece of code from here(stackoverflow) that works.
This--
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
--
What is not clear for me is why it only works on UDP and not TCP? It has something to do with the google dns server? Thanks in advance.
This has nothing to do with Google and nothing to do with DNS.
All what this code does is to "connect" a UDP socket to an external IP, so that the OS kernel figures out which local IP address it needs to use in order to reach this external system. This is no real connection, i.e. there is no traffic involved but the OS kernel is only checking routing tables and local interfaces in order to decide which IP address to use as source in case one would actually use the socket to send data.
One could do the same with TCP. But in this case a real TCP connection would be established which means that actual traffic would be exchanged and that the connect would fail if the external system would not be reachable on this port (i.e. no listener, firewall in between etc).
With UDP instead connect will not produce any traffic and would fail only if no route to the destination IP address could be determined. This also means that an arbitrary external IP address and port could be used, i.e. ('1.1.1.1',11) would work the same as ('8.8.8.8',80).

How to listen for a communication on a port without knowing what IP its coming from in python using sockets?

I am trying to make a network between some computers in python and I want to make it so that I can have another computer send information to my IP address and on a set port. Which my computer can then receiving from just listening on that port not know what IP the information has come from.
(I do not know if this is possible but any help would be amazing)
resv_conection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
resv_conection.connect(IP, PORT) # I don't want it to listen to the a specific IP, just any on that port.
I am using socket library in python.
Thank you very much,
a server must have an IP, even its 127.0.0.1 which is localhost.
The server is listening on a Port for a TCP Connection.
If you are not on the same computer, one need to check the IP for the Server.
The Server must be in same subnetwork and the IP/Port must not be blocked by a firewall.
Than the Client can connect via TCP Socket to this IP Address on a specific port.
See: https://realpython.com/python-sockets/
Use the Echo Server and Echo Client
test it locally first
after success play with the PORT see it works with changes
check the IP of the Server PC (with: "ip a" for example)
and run the Client on a different PC with changeging HOST.

Python socket taking wrong port

Why is my python script behaving this way?
I give it the instruction to connect via port 7777 but instead it is going over 45604.
I am NOT using socket.bind((socket.gethostname(),port))
Instead I work either with socket.bind(("0.0.0.0",port))
or with socket.bind(("127.0.0.1",port))
so I'm working local here. Why does my computer reroute the ports?
There should be no need for that, shouldn't it? Can I somehow disable it locally?
I am answering in the absence of any of your actual code.. So I have to make assumptions here:
1) You have server (right side in picture) listening on port 7777.
2) You are running a client on the same machine (left side of picture) that is connecting to the server.
So, the client (on the left shell) is connecting to the server (right shell window). The server is listening on 7777 and the client is connecting to the server from 45604 (client and server cannot occupy the same port on the same machine!)
Put another way, the client is "sending" to port 7777 from port 45604. Maybe that makes better sense?
A TCP connection is defined by 4 numbers: source IP address, source port, destination IP address, destination port.
The connection goes from 127.0.0.1 port 45604 to 127.0.0.1 port 7777.
The source port (45604) is a value chosen by the system from a wide range of unused ports (it is called an ephemeral port), because your program did not set a specific source port.

Sending a http get request to a server with known public ip

I have a server running by using python's base http server. The host name used is '127.0.0.1' the local host, and the port number is set to 8000. I have the public ip address of the computer operating this server.
If I wanted to send a http get request to this from another computer, what would I type into my browser?
Sounds like you've got your server process running on the wrong interface. 127.0.0.1 is not a hostname but an IP address, specifically the local loopback address. It is not reachable from any other machine (unless something's gone tragically wrong with your network configuration).
You can run anything you like on the 127.0.0.1 interface, and no one else can directly connect to it from a remote machine. That's pretty much the point --- it's for testing programs that use the Internet Protocol, and (in recent years) for starting single-user servers without worrying about security. (Python 2's SimpleHTTPServer does this, as do some personal wikis, and I think iPython Notebook.)
The public address for the host running your Web server is a completely unrelated network interface, with its own hardware and its own port 8000. It doesn't know or care that you've got something listening on some other interface's port 8000, so it should refuse attempts to connect to that port.
Since you didn't post any code, I have no idea what you need to change to get your server running on the correct interface. Assuming you've more or less followed the example in the BaseHTTPServer.HTTPServer docs:
def run(
server_class=BaseHTTPServer.HTTPServer,
handler_class=BaseHTTPServer.BaseHTTPRequestHandler,
):
server_address = ('', 8000) # <----= Replace the string.
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
That server_address tuple is a string containing the IP address ('1.2.101.202' or whatever), followed by an integer port number. So replace the string with your host machine's public-facing IP address.
Note that port 8000 is outside the reserved range (0 up to but not including 1024), so it's possible that some unrelated service is already using that port. (Numerous applications are already squatting port 8000.) If so, you'll just have to choose another port number. You can chose anything from 1024 up to but not including 65536, but as with 8000, someone else might already be using it.
Depending on your operating system and its security setup, you might not have permission to open a socket that listens on an arbitrary port number. If so, that's between you and your ISP or sysadmin.
http://yourip:port/func
yourip is your public ip.
port is 8080
func is your registered function.
and also make sure you port is opened

Categories

Resources