On Python I would like to make a python server on my public IP...
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("Public IP", 80))
s.listen(5)
conn, addr = s.accept()
But once it hits the bind command
error: [Errno 10049] The requested address is not valid in its context
How would I fix this, how would I get other people around the globe to connect to my python server.
You can only bind to an address that's configured on an interface on your local machine. Since you're using the phrase "public IP", I'm assuming that your public IP is only configured on your router, and your computer has a private address on your local network.
Have your program bind to the machine's local IP, or to any IP available (e.g, ("", 80)), then configure port forwarding on your router appropriately.
Related
I'm trying to get a socket connection between two different terminals. When they are both on the same computer, or on a different computers on the same network (behind my home router), it works fine.
Here is a minimal example of the code I use. On the client side I enter the IP address I get from running ipconfig on the server, it works with both the IPv4 Address and the Temporary IPv6 Address (changing the corresponding flag of course)
SERVER
import socket
ip_address = ""
ipv6 = False # True
PORT = 12345
STREAM = socket.SOCK_STREAM
if ipv6:
FAMILY = socket.AF_INET6
bind_args = (ip_address, PORT, 0, 0)
else:
FAMILY = socket.AF_INET
bind_args = (ip_address, PORT)
server_socket = socket.socket(FAMILY, STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(bind_args)
server_socket.listen()
unsecured_sock, client_address = server_socket.accept()
print("accepted from", client_address)
CLIENT
import socket
ip_address = "Entered from ipconfig or whatsmyip.com run from server"
ipv6 = False # True
PORT = 12345
STREAM = socket.SOCK_STREAM
if ipv6:
FAMILY = socket.AF_INET6
bind_args = (ip_address, PORT, 0, 0)
else:
FAMILY = socket.AF_INET
bind_args = (ip_address, PORT)
sock = socket.socket(FAMILY, STREAM)
sock.connect(bind_args)
print("Connected!")
The problems arise when I take one of the computers out of the home network. As I don't have two standard networks I can access at the same time, I test this by connecting one of the computers to the internet via either the 4G on my phone or through a VPN. In either case, I then use the IP I get from whatsmyip.com ran from the server. I've tried all combinations of IPv4 vs IPv6 and whether the server or the client is behind my home router. In all cases it fails (note, I don't get a IPv6 address when the server is accessing the internet via 4G on my phone). In fact, I can't even ping or tracert the ip address of the server from the client terminal.
I suspect that I'm doing something very basic wrong, but I don't know what. I suspected it was to do with port forwarding, so I tried the following UPnP script
import upnpy
upnp = upnpy.UPnP()
devices = upnp.discover()
device = upnp.get_igd()
service = device.WANIPConn1
service.AddPortMapping(
NewRemoteHost='',
NewExternalPort=12345,
NewProtocol='TCP',
NewInternalPort=12345,
NewInternalClient='192.168.0.136', # Local server IP
NewEnabled=1,
NewPortMappingDescription='Test port mapping entry from UPnPy.',
NewLeaseDuration=600)
print("added new port mapping")
which runs correctly but makes no difference. Am I right in thinking that this should be a non issue for IPv6 anyway? If it makes a difference, the provider for my internet says that my connection is IPv6 and that I do not have a proper IPv4 public address. Considering I want this to be portable and, eventually distributed, I'd rather avoid it be dependent on specific settings not accessible to the user.
Any pointers for a networking noob are most appreciated
I am currently working on a Python project to control my PC remotely from across networks. Currently I have a portmap.io connection set up, (IP: 193.xxx.xxx.xx with port 1234, I’m using an OpenVPN)
When I run my Python script:
import socket
from os import system, name
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = “193.xxx.xxx.xx”
PORT = 1234
s.bind((HOST,PORT))
s.listen(1)
conn, addr = s.accept()
s.send(b”Connection established”.encode(“utf-8”))
When I run this Python script, I get this error:
OSError: [WinError 10049] The requested address is not valid in its context
I’m almost 85% sure this is because you can’t use bind() on an ip, so what should I do? The socket needs to go across networks.
(SOLVED)
I used ngrok to create a tcp tunnel and used 0.0.0.0 as my local host, and used the provided details for the remote connection
I want to create a small TCP server that takes incoming TCP connections from a device that is hooked up via Ethernet to my computer.
The physical port for that has the IP 192.168.1.100 statically assigned to it.
The scripts I use as a client and server are listed at the bottom.
The setup works if I want to send messages between the python scripts. However, I am unable to receive anything from the external device (screenshot from Wireshark capture below). From what I have read I can define an interface to listen to by defining its IP. So I defined the IP of the interface as the host variable. However, I do not receive anything in my script but the messages sent by the other script. I had a similar situation already here on stackoverflow. I thought that defining the correct IP as the host would resolve this issue but it did not.
I am also having a hard time capturing the traffic between the two scripts with Wireshark at all. They did not show up anywhere.
I need to pick up these connections on the eth0 interface with the static IP 192.168.1.100:
tcp_server.py
import socket
# create a socket object
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
# host = socket.gethostname()
host = "192.168.1.100"
port = 9002
# bind to the port
serverSocket.bind((host, port))
# queue up to 5 requests
serverSocket.listen(5)
while True:
# establish a connection
clientSocket, addr = serverSocket.accept()
print("Got a connection from %s" % str(addr))
msg = 'Thank you for connecting' + "\r\n"
clientSocket.send(msg.encode('ascii'))
clientSocket.close()
and this as a client:
tcp_client.py
import socket
# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
# host = socket.gethostname()
host = "192.168.1.100"
port = 9002
# connection to hostname on the port.
s.connect((host, port))
# Receive no more than 1024 bytes
msg = s.recv(1024)
s.close()
print(msg.decode('ascii'))
I'm new to Sockets, please excuse my complete lack of understanding.
I have a server script(server.py):
#!/usr/bin/python
import socket #import the socket module
s = socket.socket() #Create a socket object
host = socket.gethostname() #Get the local machine name
port = 12397 # Reserve a port for your service
s.bind((host,port)) #Bind to the port
s.listen(5) #Wait for the client connection
while True:
c,addr = s.accept() #Establish a connection with the client
print "Got connection from", addr
c.send("Thank you for connecting!")
c.close()
and client script (client.py):
#!/usr/bin/python
import socket #import socket module
s = socket.socket() #create a socket object
host = '192.168.1.94' #Host i.p
port = 12397 #Reserve a port for your service
s.connect((host,port))
print s.recv(1024)
s.close
I go to my desktop terminal and start the script by typing:
python server.py
after which, I go to my laptop terminal and start the client script:
python client.py
but I get the following error:
File "client.py", line 9, in
s.connect((host,port))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused
I've tried using different port numbers to no avail. However, I was able to get the host name using the same ip and the gethostname() method in the client script and I can ping the desktop (server).
Instead of
host = socket.gethostname() #Get the local machine name
port = 12397 # Reserve a port for your service
s.bind((host,port)) #Bind to the port
you should try
port = 12397 # Reserve a port for your service
s.bind(('', port)) #Bind to the port
so that the listening socket isn't too restricted. Maybe otherwise the listening only occurs on one interface which, in turn, isn't related with the local network.
One example could be that it only listens to 127.0.0.1, which makes connecting from a different host impossible.
This error means that for whatever reason the client cannot connect to the port on the computer running server script. This can be caused by few things, like lack of routing to the destination, but since you can ping the server, it should not be the case. The other reason might be that you have a firewall somewhere between your client and the server - it could be on server itself or on the client. Given your network addressing, I assume both server and client are on the same LAN, so there shouldn't be any router/firewall involved that could block the traffic. In this case, I'd try the following:
check if you really have that port listening on the server (this should tell you if your code does what you think it should): based on your OS, but on linux you could do something like netstat -ntulp
check from the server, if you're accepting the connections to the server: again based on your OS, but telnet LISTENING_IP LISTENING_PORT should do the job
check if you can access the port of the server from the client, but not using the code: just us the telnet (or appropriate command for your OS) from the client
and then let us know the findings.
Assume s = socket.socket()
The server can be bound by following methods:
Method 1:
host = socket.gethostname()
s.bind((host, port))
Method 2:
host = socket.gethostbyname("localhost") #Note the extra letters "by"
s.bind((host, port))
Method 3:
host = socket.gethostbyname("192.168.1.48")
s.bind((host, port))
If you do not exactly use same method on the client side, you will get the error: socket.error errno 111 connection refused.
So, you have to use on the client side exactly same method to get the host, as you do on the server. For example, in case of client, you will correspondingly use following methods:
Method 1:
host = socket.gethostname()
s.connect((host, port))
Method 2:
host = socket.gethostbyname("localhost") # Get local machine name
s.connect((host, port))
Method 3:
host = socket.gethostbyname("192.168.1.48") # Get local machine name
s.connect((host, port))
Hope that resolves the problem.
host = socket.gethostname() # Get the local machine name
port = 12397 # Reserve a port for your service
s.bind((host,port)) # Bind to the port
I think this error may related to the DNS resolution.
This sentence host = socket.gethostname() get the host name, but if the operating system can not resolve the host name to local address, you would get the error.
Linux operating system can modify the /etc/hosts file, add one line in it. It looks like below( 'hostname' is which socket.gethostname() got).
127.0.0.1 hostname
in your server.py file make : host ='192.168.1.94' instead of host = socket.gethostname()
Pay attention to change the port number. Sometimes, you need just to change the port number. I experienced that when i made changes over changes over syntax and functions.
I was being able to ping my connection but was STILL getting the 'connection refused' error. Turns out I was pinging myself! That's what the problem was.
I was getting the same problem in my code, and after thow days of search i finally found the solution, and the problem is the function socket.gethostbyname(socket.gethostname) doesnt work in linux so instead of that you have to use socket.gethostbyname('put the hostname manually') not socket.gethostbyname('localhost'), use socket.gethostbyname('host') looking with ifconfig.
try this command in terminal:
sudo ufw enable
ufw allow 12397
i already have a post which is quite similiar, but i am getting more and more frustrated because it seems nothing is wrong with my network setup. Other software can be seen from the outside (netcat listen servers etc.) but not my scripts.. How can this be??
Note: It works on LAN but not over the internet.
Server:
import socket
host = ''
port = 80001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print 'Listening..'
conn, addr = s.accept()
print 'is up and running.'
print addr, 'connected.'
s.close()
print 'shut down.'
Client:
import socket
host = '80.xxx.xxx.xxx'
port = 80001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
s.close()
Somebody please help me.
Any help is greatly appreciated.
Jake
Edited again to add:
I think you may be missing some basics on socket communication. In order for sockets to work, you need to ensure that the sockets on both your client and server will meet. With your latest revision, your server is now bound to port 63001, but on the local loopback adapter: 127.0.0.1
Computers have multiple network adapters, at least 2: one is the local loopback, which allows you to make network connections to the same machine in a fast, performant manner (for testing, ipc etc), and a network adapter that lets you connect to an actual network. Many computers may have many more adapters (virtual adapters for vlans, wireless vs wired adapters etc), but they will have at least 2.
So in your server application, you need to instruct it to bind the socket to the proper network adapter.
host = ''
port = 63001
bind(host,port)
What this does in python is binds the socket to the loopback adapter (or 127.0.0.1/localhost).
In your client application you have:
host = '80.xxx.xxx.xxx'
port = 63001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
Now what your client attempts to do is to connect to a socket to port 63001 on 80.xxx.xxx.xxx (which is your wireless internet adapter).
Since your server is listening on your loopback adapter, and your client is trying to connect on your wireless adapter, it's failing, because the two ends don't meet.
So you have two solutions here:
Change the client to connect to localhost by host = 127.0.0.1
Change the server to bind to your internet adapter by changing host = 80.xxx.xxx.xxx
Now the first solution, using localhost, will only work when your server and client are on the same machine. Localhost always points back to itself (hence loopback), no matter what machine you try. So if/when you decide to take your client/server to the internet, you will have to bind to a network adapter that is on the internet.
Edited to add:**
Okay with your latest revision it still won't work because 65535 is the largest post available.
Answer below was to the original revision of the question.
In your code posted, you're listening (bound) on port 63001, but your client application is trying to connect to port 80. Thats why your client can't talk to your server. Your client needs to connect using port 63001 not port 80.
Also, unless you're running an HTTP server (or your python server will handle HTTP requests), you really shouldn't bind to port 80.
In your client code change:
import socket
host = '80.xxx.xxx.xxx'
port = 63001
And in your Server Code:
import socket
host = ''
port = 63001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostbyname(socket.gethostname()), port ))
In your server script you have port = 80, but you don't ever use it. It looks like the server is listening on 63001. And the client is connecting to 80.
If you're going to use 80, make sure you don't have an http server trying to use the port at the same time as well.