Python Sockets Cant Find Each Other on the Same Network - python

I have seen so many of these questions being asked before but none of the solutions seem to apply to my case. I set up a server and a client socket script to communicate with each other. Whenever I run them on the same machine, they work and the server prints "Connection received" but when I run them on different machines, they don't. The IP is the IP of the server, I have disabled my windows firewalls/antivirus and I am certain they are both on the same network. When attempting to connect, it stalls for about 20 seconds then gives error 10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
Some info that may be useful:
Server: Raspberry Pi 3b, Python 3.4.2
Client: Windows 10 PC, Python 3.7.8
Note: These scripts used to work in the past. I don't use them frequently so I don't know exactly when they stopped working, but I assume it was around the time we switched our internet package as this also broke some of our wireless smart home devices.
Does anyone know why they can't find/connect to each other? Thanks.
Server Code
import socket
from time import sleep
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('192.168.0.34', 1234))
s.listen(5)
clientsocket = None
print("Listening")
while True:
clientsocket, address = s.accept()
print("Connection Received")
break
#The code that runs after a client successfully connects
Client Code
import socket
from time import sleep
print("Looking")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.0.34', 1234))
print("Connected")
sleep(20) #This is just so I can read any errors before the window closes for testing.
#code to start sending data

Related

python socket does not connect to other networks

hi guys i'm studying socket in python, i'm having a hard time connecting with other machines
I have this simple code
import socket
host = ''
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host, 222))
print('wait...')
sock. listen(1)
conn, addr = sock.accept()
print('connected')
the code above is a server, I try to connect using this simple code
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('192.168.0.14', 222))
when I execute the client code, nothing happens, it is in an infinite wait, neither the server responds nor the client responds.
obs: this is my goal to connect to an external network on my network. The server code is running on another network, I want to connect to another network
I ran your code, and it's basically correct. But I don't think your port is perfect, it should be at least 1024.
You should make sure that the port(222) in firewall on your server computer is open.
I changed your port to 12345, it works on my computer.

How to connect my server to other machine using socket library in Python?

I am new to socket library and server side programming. I made 2 scripts which runs perfectly on my machine i.e. server.py and client.py. But when i test it on two different computers it doesn't worked.
What i want is to make my server.py file connected to client.py,
where server.py will run on my machine and it will be connected to
client.py on a separate machine at any location in the world.
I just know socket only. But if this problem can be solved by use of other library, then also it will be fine.
Here is my code:
server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostbyname(socket.gethostname())
port = 12048
s.bind((host, port))
s.listen()
print("Server listening # {}:{}".format(host, port))
while True:
c, addr = s.accept()
print("Got connection from", addr)
c.send(bytes("Thank you", "utf-8"))
client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '192.168.1.162' # The IP printed by the server must be set here
port = 12048
s.connect((socket.gethostname(), port))
msg = s.recv(1024)
print(msg.decode("utf-8"))
I don't know how it's possible but if it is then please answer this.
Also, i want to receive files from client.py to my machine. Is it possible in socket or i have to import any other library?
Any help will be appreciated.
The reason the client will only connect to the server running on the same computer is because you are using s.connect((socket.gethostname(), port)) instead of s.connect((host, port)). Your host IP variable is never being used. This error means that the client will be trying to connect to its own hostname, which would be itself, and so that is why it only works on one single computer.
You should modify client.py like this:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '192.168.1.162' # Make sure this is set to the IP of the server
port = 12048
s.connect((host, port))
msg = s.recv(1024)
print(msg.decode("utf-8"))
Now you will be able to connect to a server running on a different computer.
In Client.py you're connecting the socket to socket.gethostname() instead of the ip address of your server. Now, your client is trying to a server that should be running on the same ip as the client. Logically this will work when server and client run on the same ip, but when the client resides on another machine you need to connect to the correct ip address:
s.connect((host, port))
Also, make sure that port is actually open and not blocked by another program. This website helped me open port 7777 on two different laptops and run your edited code on them. You can do the same for port 12048.
Right-click the Start button.
Click Search.
Type Windows Firewall.
Click Windows Firewall.
Click Advanced settings.
Click Inbound Rules in the left frame of the window.
Click New Ruleā€¦ in the right frame of the window.
Click Port.
Click Next.
Click either TCP or UDP.
Click Specific local ports.
Type a port number. (In this case, we will open port 12048.)
Click Next.
Click Allow the connection.
Click Next.
Click any network types you'd like to allow the connection over.
Click Next.
Type a name for the rule.
Click Finish.
I believe for a socket you have to open the TCP port but if that doesn't work you can make a new rule for the UDP port as well.

How to send socket message when Server has a preset initial response?

I'm making python binds for Blackmagic's Ethernet Control Protocol ( as documented in https://documents.blackmagicdesign.com/UserManuals/HyperDeckManual.pdf?_v=1528269592000 , page 60). Simple socket connection seems to fail however, because every commands gets rejected with the server's greeting.
This protocol documents how software can communicate with certain blackmagic devices, in this case, Blackmagic's hyperdeck, the device runs a TCP server constantly listening on port 9993, on cmd I can simply telnet to it and issue commands, you'd it expect it to be as straightforward in python, however every command gets ignored for the server's greeting message, the device's information. I have been doing socket's for at least 3 months now and i've tried several methods of code, and all seem to fail.
For the most trivial test i've used:
import socket
HOST = "device's ip"
PORT = 9993
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'play')
data = s.recv(1024)
print(data)
and a modified version to try to repeat the command:
import socket
import time
HOST = "device's ip"
PORT = 9993
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'play')
data = s.recv(1024)
time.sleep(2)
s.sendall(b'play')
It should start video playback, as documented, and as occurs when I issue the command thru telnet, however the command is completely ignored and data always equals to: b'500 connection info:\r\nprotocol version: 1.9\r\nmodel: HyperDeck Studio Mini\r\n\r\n' , the server's greeting message in byte form, it should instead be 200 ok or some sort of error / acknowledged message, as documented.
This is incredibly annoying and i've thought of using subprocess and issuing commands thru cmd as an alternative, but something tells me there's an easier workaround.

Python sockets, two computers on same wifi

I have two python (python 3) programs, one client and one server.
Client.py:
import socket
import time
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('192.168.0.18', 8087))
clientsocket.send(b'a')
time.sleep(0.05)
clientsocket.close()
Server.py:
import socket
import time
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('', 8087))
serversocket.listen(5)
connection, address = serversocket.accept()
b = connection.recv(1)
time.sleep(0.1)
serversocket.close()
connection.shutdown(socket.SHUT_WR)
connection.close()
print(b)
All it does is connecting a client and a server, and then sending the char 'a' from the client to the server. If I run both on them on the same computer, it works fine and the server prints 'a'. However, if I run the server on one computer and the client on another computer (both connected on the same wireless network), they get stuck on clientsocket.connect respectively serversocket.accept (and ultimately times out). The IP address is obtained by running ifconfig and pick the number after 'inet addr'.
How can I troubleshoot this problem? Is the firewall stopping my computer from taking connections?
I know there are other similar questions on stackoverflow, but none of them describe exactly this situation and the answers do not help me.

How to trigger Raspberry Pi 3 to take action from Server

I am currently developing a system where I need to send notification to Raspberry to run a Python file. It is much like a observer pattern design where my server is publisher and Raspberry is the observer. Worth to note that, I actually need to interact with one Raspberry at the time (even I have dozens of them). Specifically, on a specific event, I need to warn a single Raspberry that it has to take an action.
I searched for it literally for all the night but I could not find anything coming handy. Nothing really give me a clue how to implement this.
The most close answer I could find is this technology firm's product called PubNub which can actually work. However, as I need is a one-to-one interaction, this might be unnecessary because it is designed to publish a data to multiple clients.
Long story short, I need to trigger Raspberry to take some action in accordance to the some data coming from the server, whenever it receives the data.
Server is running on Amazon and implemented with Python 2.7.
Please do not hesitate to ask me for further detail, if I am missing any.
Thanks for all the supports,
EDIT
Just a recent update with an improvement to my answer. As far as I understand, sockets are able to manage this process. Such as from client (Raspberry in my case) listening for the server and server sending some data. Taken from this site, I managed to make a sample run on my computer, from my local. I used Port 5000 as their 'meeting point'.
Below is the code:
client.py
#!/usr/bin/env python
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 5000
BUFFER_SIZE = 1024
MESSAGE = b"Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()
print("received data:", data)
server.py
#!/usr/bin/env python
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 5000
BUFFER_SIZE = 20 # Normally 1024, but we want fast response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
print('Connection address:', addr)
while 1:
data = conn.recv(BUFFER_SIZE)
if not data: break
print("received data:", data)
conn.send(data) # echo
conn.close()
However, I still have some questions.
Firstly, I want to learn whether the same thing work when I deploy the project and how. If that will work - lets say I have an url for the server like 'www.thisisanexampleurl.com' - simply assignign a port for it, will work?
Secondly, assuming first question is done, what is the way of making it continous so that it does not stop after receiving and sending data once. Because currently, when it makes the data transfer, it stops working.
Thanks again for the all support and again please do not hesitate to ask me for the further details i am missing any.
You should be able to do something this simple:
Run something like this on your pi:
import socket
s = socket.socket()
host = ""
port = 12345
s.bind((host, port))
s.listen(5)
while True:
try:
clientsock, addr = s.accept()
except OSError:
continue
message = clientsock.recv(20)
#the code you want to run
print("doing %s" % message)
clientsock.close()
And this on your server every time you want the pi to take action:
import socket
s = socket.socket()
host = "0.0.0.0"
port = 12345
s.connect((host, port))
s.send("foo")
s.close()
Have a look at Pyro4. It lets you avoid having to write network code at all and just write code that calls remote Python objects as if they were running on the same machine. In your case, the server could call a normal Python method on your Raspberry Pi to do something. It has many features but you can start with something extremely simple.
raspberry pi code:
import Pyro4
#Pyro4.expose
class Raspberry:
def something(self, arg):
print("called with:", arg)
return "hi from pi"
Pyro4.Daemon.serveSimple({Raspberry: "raspberry"})
server code to make the pi do something:
import Pyro4
rasp = Pyro4.Proxy("PYRONAME:raspberry")
print(rasp.something(42))

Categories