I'm using MicroPython with two NodeMCU ESP8266 dev boards. My goal is to connect one to the other, so they can interchange information. One of the boards is running a server program and its AP is up. The other connects to the other board's AP and try to connect.
The server is running fine, and I can connect to it with Kitty using a RAW connection (connecting my PC to the ESP8266 AP). The client, instead, fails in socket.connect() and throws a ECONNABORTED exception. I've used differents settings, but none of them seems to work. How can I connect my two boards? I'm a newbie with sockets, so this may be not a MicroPython specific problem but a Python one.
EDIT: There's no problem when connecting from a PC using the same code. The problem seems to be exclusive of a client ESP8266 connecting to a server ESP8266 through the server Access Point. Maybe a MicroPython bug?
Server code:
import network
import socket
def runServer():
try:
ap_if = network.WLAN(network.AP_IF)
ap_if.active(True)
ap_if.config(essid='MicroPy-AP', password='micropythoN')
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind( ('', 8266) )
s.listen(1)
print("Waiting for a client...")
client, client_ip = s.accept()
print("Connected!")
finally:
print("Closing socket...", end=' ')
s.close()
print("Done.")
Client code:
import network
import socket
def runClient():
try:
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('MicroPy-AP', 'micropythoN')
while not sta_if.isconnected():
pass
sta_if.ifconfig()
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print("Connecting...")
s.connect( ('192.168.4.1', 8266) )
finally:
print("Closing socket...", end=' ')
s.close()
print("Done.")
The stupid answer to this question is that I eventualy switched the programs between the boards, so both of them was running with an 'almost' identical (ESSID and password) Access Point. Although the client was correctly connected to the server AP, I guess that some IP conflict was avoiding the socket to connect.
Related
I've been recently introduced to the standard socket module in python, and have begun experimenting with it myself. However, upon sending my projects to friends, I've soon bumped into the problem that the programs have only local network reach.
Here's an example of what I've been working on- it's a simple program that connects a server to one client, then engages them in a simple chat loop indefinetly.
This program has been copied from this video tutorial, with some modifications:
https://www.youtube.com/watch?v=YwWfKitB8aA&t=1614s
(IP has been slightly modified for privacy purposes.)
SERVER:
import socket
HOST = '192.168.0.1'
PORT = 43218
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
commsocket, address = server.accept()
print(f"Connected to {address}")
while(True):
message = commsocket.recv(1024).decode("utf-8")
print(f"Message from client: {message}")
returnmessage = input("Type in message to send: ")
commsocket.send(returnmessage.encode('utf-8'))
CLIENT:
import socket
from time import sleep
HOST = '192.168.0.1'
PORT = 43218
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.connect((HOST, PORT))
while(True):
message = input("Type in message to send, then press enter: ")
server.send(message.encode('utf-8'))
print(f"Message from server {server.recv(1024).decode('utf-8')}")
Is it in any way possible to modify this so that anyone from outside my LAN (if possible, even to a global reach) can use this program as a client? If possible, with only the use of the vanilla socket module.
Thank you
I am trying to build a connection between a server and one or more clients in Python using sockets. My code works just fine when I connect with a client in the same network, but my goal is to build a program which me and my friend can use, so I want to figure out a way to connect to my server from an external network via the internet.
My server-side code looks like this:
import socket
server = "internal_ip"
port = 5006
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
serv.bind((server, port))
print(server)
except socket.error as e:
print(e)
serv.listen(2)
while True:
conn, addr = serv.accept()
from_client = ""
while True:
data = conn.recv(4096)
if not data:
break
from_client += str(data)
print(from_client)
conn.send(str.encode("I am SERVER"))
conn.close()
print("Client disconnected")
And this is my client:
import socket
server = "internal_ip"
port = 5006
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect((server, port))
except socket.error as e:
print(e)
while True:
try:
client.send(str.encode("I am CLIENT"))
from_server = client.recv(4096)
#client.close()
print(from_server)
except:
break
client.close()
This works just fine within a network. Then I started testing the code from an external client. I changed the ip to my external ip address which I have found using whatismyipaddress.com, and port number to a different one than I use on the server side.
server = "external_ip"
port = 5007
Then I enabled port forwarding using cmd:
netsh interface portproxy add v4tov4 listenport=5007 listenaddress=external_ip connectport=5006 connectaddress=internal_ip
I get WinError 10060. Tried switching firewall on and off, and allowing these specific ports, but I can't make it work.
Can you help me with my problem please?
I'm reading about socket module in a web learning site about python, they gave us a simple steps to use socket module like follows:
import socket
with socket.socket() as client_socket:
hostname = '127.0.0.1'
port = 9090
address = (hostname, port)
client_socket.connect(address)
data = 'Wake up, Neo'
data = data.encode()
client_socket.send(data)
response = client_socket.recv(1024)
response = response.decode()
print(response)
when executing I got the error message:
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it.
when I searched about this some sites was talking about server listening and I see in most of tutorials about server socket and they use it along with client one.
so Is the error message related to the fact that I'm not using a server socket and is it a must to use them both
Update:
after reading the answers I got, I went to the test.py file that the course instructors use to evaluate our codes and I see that they make the server socket in it , so the server is already made by them. that take me back to the Error I got why does it happen then.
def server(self):
'''function - creating a server and answering clients'''
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(('localhost', 9090))
self.ready = True
try:
self.sock.listen(1)
conn, addr = self.sock.accept()
self.connected = True
conn.settimeout(15)
while True:
data = conn.recv(1024)
self.message.append(data.decode('utf8'))
if len(self.message) > 1_000_000:
conn.send(
json.dumps({
'result': 'Too many attempts to connect!'
}).encode('utf8'))
break
if not data:
break
Each connection requires a client, which initiates the connection, and a server, which listens for the incoming connection from the client. The code you have shown is for the client end of the connection. In order for this to run successfully you will need a server listening for the connection you are trying to create.
In the code you showed us you have the lines
hostname = '127.0.0.1'
port = 9090
address = (hostname, port)
client_socket.connect(address)
These are the lines that define what server you are connecting to. In this case it is a server at 127.0.0.1 (which is localhost, the same machine you are running the code on) listening on port 9090.
If you want to make your own server then you can look at the documentation for Python sockets and the particular functions you want to know about are bind, listen, and accept. You can find examples at the bottom of that same page.
Given that you appear to have found this code as part of a course, I suspect they may provide you with matching server code at some point in order to be able to use this example.
recently I've been messing around with sockets in python and i needed to connect to a remote server for a project. I know there are plenty of questions about this topic but none of the solutions worked for me and i am about to go mad if i can't get this to work.
Server code:
import socket
import threading
FORMAT = "UTF-8"
PORT = 55555
SERVER = ''
ADDR = ('0.0.0.0', PORT)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
conn.send("Test".encode(FORMAT))
def start():
server.listen()
print(f"[LISTENING] Server is listening on {PORT}")
while True:
connection, adress = server.accept()
thread = threading.Thread(target=handle_client, args=(connection, adress))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting...")
start()
Client Code:
import socket
import threading
FORMAT = "UTF-8"
PORT = 55555
SERVER = "xx.xxx.xxx.xxx" # public ip
print(f"\nconnecting... {PORT}\n")
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect(ADDR)
except:
print("Couldnt connect.")
print(client.recv(1024).decode(FORMAT))
When i change the SERVER variable in client script to my local ip (192.168.1.34), i can run these two scripts in two different pcs in the same LAN and it works well, i recieve the "Test" message in my client pc.
However, when i change the SERVER variable to my public ip and run the server in my server pc, i can't connect to the client pc. Here, my server and client pcs are NOT in the same network. Server is connected to my router whereas client is in another network. When i run the client script nothing happens and after a while i get [WINERROR 10057]
I've done port forwarding to port 55555. I tried disabling all firewalls and even creating a new rule in windows firewall to allow connections from port 55555. It still doesn't work and i can't figure out why.
If there is anyone who can see the problem here i would really appreciate it.
The only thing I can see that maybe is causing a problem is in your ADDR variable. I recently did a similar project that was successful, and in my sever code I did the equivalent of:
ADDR('',PORT)
I don't know for sure this would fix your problem, but it is my best guess from the info you provided.
I am trying to make a simple app in Python with sockets, but clients only receive the message "Test" sent from the server if they're in the LAN. I tried to run the client (the server is running on my PC) from my laptop and from my PC. In both cases I received the message "Test", but when a friend tries to connect he doesn't receive the message.
Here is my server.py:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 7908))
s.listen(5)
while True:
clientsocket, address = s.accept()
print(f"Connection from {address} established")
clientsocket.send(bytes("Test", "utf-8"))
And here is my client.py:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("my_public_ip_address", 7908))
print(s.recv(8).decode("utf-8"))
I compile client.py with pyinstaller before sending it, so that the script can run without Python being installed on the machine (I don't even have Python on my laptop)
Thanks for taking the time to read and awnsering this :) (Sorry if my english is bad, I'm french)
I guess your friend is outside your LAN: if so you should open/portforward port 7908 on the router to the server.
Open port 7908 on the sever PC firewall.
Your script in this way should work.