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.
Related
On Windows 10 I want to read data from UDP port 9001. I have created the following script which does not give any output (python 3.10.9):
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("", 9001))
while True:
data, addr = sock.recv(1024)
print(f"received message: {data.decode()} from {addr}")
I checked that a device is sending UDP data on port 9001 using wireshark. But the above code just "runs" on powershell without any output (and without any errors).
Any ideas how to fix this?
I found this page with a powershell script that is supposed to listen to a UDP port. So I tried this and created a file Start-UDPServer.ps1 with the content as described in that page as follows:
function Start-UDPServer {
[CmdletBinding()]
param (
# Parameter help description
[Parameter(Mandatory = $false)]
$Port = 10000
)
# Create a endpoint that represents the remote host from which the data was sent.
$RemoteComputer = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Any, 0)
Write-Host "Server is waiting for connections - $($UdpObject.Client.LocalEndPoint)"
Write-Host "Stop with CRTL + C"
# Loop de Loop
do {
# Create a UDP listender on Port $Port
$UdpObject = New-Object System.Net.Sockets.UdpClient($Port)
# Return the UDP datagram that was sent by the remote host
$ReceiveBytes = $UdpObject.Receive([ref]$RemoteComputer)
# Close UDP connection
$UdpObject.Close()
# Convert received UDP datagram from Bytes to String
$ASCIIEncoding = New-Object System.Text.ASCIIEncoding
[string]$ReturnString = $ASCIIEncoding.GetString($ReceiveBytes)
# Output information
[PSCustomObject]#{
LocalDateTime = $(Get-Date -UFormat "%Y-%m-%d %T")
SourceIP = $RemoteComputer.address.ToString()
SourcePort = $RemoteComputer.Port.ToString()
Payload = $ReturnString
}
} while (1)
}
and started it in an Powershell terminal (as admin) as
.\Start-UDPServer.ps1 -Port 9001
and it returned to the Powershell immediately without ANY output (or error message). Maybe windows is broken?
If there is a solution to finally listen to UDP port 9001, I still strongly prefer a python solution!
As far as I can see, your posted Python code should have given you an error when run if it was receiving any data, so that suggests that the data was not getting to the process at all.
I'd recommend checking your Windows Firewall settings for that port, and any other host-based firewalls you might be running.
But also, the recv() method does not return a tuple. recvfrom() does, so the following code works:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("", 9001))
while True:
data, addr = sock.recvfrom(1024)
print(f"received message: {data.decode()} from {addr}")
A tangential note: the Powershell script does not actually start a UDP server, it just creates a function to do so. So you need to add a line Start-UDPServer -Port 9001 at the end to call the function if you want it to actually listen for datagrams.
Server code:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 81))
client = []
print('Start Server')
while 1:
data, addres = sock.recvfrom(1024)
print(addres[0], addres[1])
if addres not in client:
client.append(addres)
for clients in client:
sock.sendto(data, clients)
Client code:
import socket
import threading
def read_sok():
while 1 :
data = sor.recv(1024)
print(data.decode('utf-8'))
server = '54.236.40.62', 81 # Public IP
alias = input()
sor = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sor.bind(('', 0))
sor.sendto((alias+' Connect to server').encode('utf-8'), server)
potok = threading.Thread(target= read_sok)
potok.start()
while 1 :
mensahe = input()
sor.sendto(('['+alias+']'+mensahe).encode('utf-8'), server)
The server OS is the linux ubuntu(third in quick start).
Python 3.10.6 is on the server. 3.11.1 on the client.
The server must resend incoming message to everyone clients, which have ever sent messages to it(including the client, who sent this message). When everything is ok, the client sends a message to the server and receives it back.
The problem is that the client(on my PC) can't interact with the sever. It just can't see the server. The client sends the message to the server and does not receive the message(the same situation when the server is turned off or the IP is incorrect for it).
1)These codes work fine if they are on the same PC or on the same network.
2)I didn't forget about security group settings. Port 81 is opened as 80. I started apache2 default page through 80 and it works well in the browser. I also tried using port 80(which certainly works well) for python server(unsuccessful).
3) I know that I can't use public IP for sock.bind(('', 81)). I tried using both sock.bind(('', 81)) and sock.bind(('Private_IP', 81)) cases.
4) I also used ports like 12345 and etc.
I would be grateful for any advice:)
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
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.
I'm currently working on with Sockets using Python.
As a starter, I tried copying first the examples given in this (17.2.2. Example) tutorial
I put the client and the server scripts in two different machines (of course)
Now, I want to try if it works, but I'm kind of lost.
I'm thinking of running the server program continuously so that it will keep on receiving the data sent by the client program. However, when I tried to run the Server program, it is giving me this error
socket.error: (99, 'Cannot assign requested address')
and When I tried running the client program, it doesnt give me errors, however, it is printing random data, which is different from what I'm expecting because I sent the String "Hello World", So im expecting that it will receive and print "Hello World"
Shown below is the server program
# Echo server program
import socket
HOST = '192.168.104.112' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()
and the one below is the client program
# Echo client program
import socket
HOST = '192.168.104.111' # The remote host
PORT = 50007 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)
Assuming that the IP of the machine that runs the server program is : 192.168.104.111
while the Client program is : 192.168.104.112
Im not really sure where to get the port number so I just used the port showed in the rpyc in the terminal. how do I get the correct port number anyway?
I know I made a lot of mistakes here. I just don't which part. Could you point me the mistakes that i've done and how to correct them? and how do I run these programs?
BTW, i'm using Centos.
On the server, HOST should be either 0.0.0.0 or the server's own IP address. The server needs to bind its listening port to its own interface(s). The client connects to the server.
Your client program doesn't check for errors. So if it can't connect to the server, things go awry.