Can't receive an answer from python socket - linux

I have a working command for linux that sends a request and gets a response:
echo -n -e '\x9e\x4c\x23\x00\x00\xff\xff\xce\xf2\x3b\x18\x80' | nc -u -w 1 -p 11244 127.0.0.1 11235
I'm trying to do the same through the python:
import socket
IP = "127.0.0.1"
PORT = 11235
MESSAGE = "9e4c230000ffffcef23b1880"
BINARY_MESSAGE = MESSAGE.decode('hex')
print ("BINARY_MESSAGE: [%s]" % BINARY_MESSAGE) # <- message is the same as echo -en does
srvsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srvsock.settimeout(3) # 3 seconds
srvsock.connect((IP, PORT))
srvsock.sendall(BINARY_MESSAGE)
data = srvsock.recv(4096)
print ("Received message: [%s]" % data)
srvsock.close()
I receive a blank responce:
BINARY_MESSAGE: [�L#����;�]
Received message: []
I guess I'm doing something wrong.

Your nc command line is using UDP (-u). Your Python code is using TCP (socket.SOCK_STREAM). You want to create a UDP socket:
srvsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
You will want to get rid of the call to connect, but you will need a call bind if you expect to receive messages on that socket. For example, the following code sends a message then waits for a reply on the same socket:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('127.0.0.1', 2222))
s.sendto('this is a test', ('127.0.0.1', 3333))
data, srcaddr = s.recvfrom(1024)
print(data, srcaddr)
Remember that UDP is a connectionless protocol. The other side of this conversation can't "reply" to the message; it needs to explicitly send to the address/port on which the above code is listening. In Python the other side of this conversation might look like:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('127.0.0.1', 3333))
data, srcaddr = s.recvfrom(1024)
print(data)
s.sendto('that was a test', srcaddr)
The above code waits for a message then sends a response back.

Related

Python3 Socket Rtsp wrong response

I am trying read the status code using socket from a rtsp stream.
unfortunately the response is always 401...
'RTSP/1.0 401 Unauthorized\r\nCSeq: 0\r\nWWW-Authenticate: Digest realm="Login to PA6BG0123456", nonce="1234567891234565"\r\n\r\n'
...however i am sure the route and password are correct
rtsp://admin:admin#192.168.0.5:554/cam/realmonitor?channel=1&subtype=0
works perfectly using vlc and ffmpeg.
Snipped code
import socket
PORT = 554
IP = '192.168.0.5'
TIMEOUT = 5
CRED = 'admin:admin'
PATH = '/cam/realmonitor?channel=1&subtype=0'
#create describe packet
global DESCRIBEPACKET
DESCRIBEPACKET = 'DESCRIBE rtsp://%s#%s%s RTSP/1.0\r\n' % (CRED, IP, PATH)
DESCRIBEPACKET += 'CSeq: 2\r\n'
DESCRIBEPACKET += 'Accept: application/sdp\r\n'
DESCRIBEPACKET += 'User-Agent: Mozilla/5.0\r\n\r\n'
print(DESCRIBEPACKET) #for debug
#connect to socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(TIMEOUT)
s.connect((IP, PORT))
s.sendto(DESCRIBEPACKET.encode(), (IP, PORT))
data = repr(s.recv(1024))
print(data) #For debug sends me the wrong 401 response
s.close()
Any ideas what am i doing wrong?

Can't receive multiple messages on server using TCP socket (Python)

I am new to sockets and don't really know how to receive multiple messages from the same client. I only receive the first message and not the rest.
Server code:
import socket
IP = "127.0.0.1"
PORT = 65432
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((IP, PORT))
server.listen()
while True:
communication_socket, address = server.accept()
msg = communication_socket.recv(1024).decode("utf-8")
print(msg)
Client code:
import socket
import time
HOST = "127.0.0.1"
PORT = 65432
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((HOST, PORT))
socket.send("success".encode("utf-8"))
time.sleep(2)
socket.send("?".encode("utf-8"))
socket.close()
communication_socket, address = server.accept()
msg = communication_socket.recv(1024).decode("utf-8")
The current code accepts the new connection and then does a single recv. That's why it gets only the first data. What you need are multiple recv here after the accept.
... multiple messages from the same client
TCP has no concept of messages. It is only a byte stream. There is no guaranteed 1:1 relation between send and recv, even if it might look like this in many situations. Thus message semantics must be an explicit part of the application protocol, like delimiting messages with new lines, having only fixed size messages or similar.

How to initiate a socket connection from server to client?

I have setup a tcp socket between a client and a server, very basic. Client side:
#!/usr/bin/env python3
import socket
# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = "81.88.95.250"
port = 25000
# 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'))
server side:
#!/usr/bin/env python3
import socket
# create a socket object
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 25000
# 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()
My target is to send notification from client to server, and that's easy. The difficult part is that I also need in some circumstances to start the connection from the server and to send a command to the client and this must be executed as soon as it is received, so I cannot setup a periodic "poll". But I'm quite confused on this part, because the client is behind a NAT, not exposed with a public IP.

Can't set timeout for python 3 recv

I am trying to get a time out on the code below. But it just hangs at the recv and never times out. Can someone point to what I am doing wrong? I have looked and I can't seem to find too much on it.
import socket
host = "localhost"
port = 8888
# create socket object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# give object the ip and port to listen on
server_address = (host, port)
print('starting up on %s port %s' % server_address)
sock.bind(server_address)
# how many listeners
sock.listen(0)
# sets the time out
sock.settimeout(10)
while True:
print('waiting for a connection')
try:
#this waits for a connection from the sending side.
connection, client_address = sock.accept()
print('connection from', client_address)
start = False
message = ""
while client_address != "":
#this listens and waits for data to be sent and sets it to the data variable
data = connection.recv(32000).decode()
You have set an accept timeout on the listening socket, not a read timeout on the receiving socket.

python3: two clients sending data to server using sockets

I'm working with 3 raspberry pi, one as a server and the two others are clients. What I want to do is to make the clients communicate with the server simultaneously, I don't want to wait for client1 communication to be done in order to launch client2 request to the server (which I succeeded to do). However, I want each client to send different data to server at the same time. I tried to use Sockets and threading, like below.
server code:
import socket
import RPi.GPIO as GPIO
from threading import Thread
# Multithreaded Python server : TCP Server Socket Thread Pool
class ClientThread(Thread):
def __init__(self,ip,port):
Thread.__init__(self)
self.ip = ip
self.port = port
print ("[+] New server socket thread started for " + ip + ":" + str(port))
def run(self):
while True :
data = conn.recv(2048)
data = data.decode('utf-8')
print ("Server received data:", data)
MESSAGE = input("Multithreaded Python server : Enter Response from Server/Enter exit:")
if MESSAGE == 'exit':
break
conn.send(str.encode(MESSAGE)) # echo
# Multithreaded Python server : TCP Server Socket Program Stub
TCP_IP = ''
TCP_PORT = 9050
BUFFER_SIZE = 2000 # Usually 1024, but we need quick response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(2)
threads = []
list_data=[]
while True:
print ("Multithreaded Python server : Waiting for connections from TCP clients...")
(conn, (ip,port)) = s.accept()
data = conn.recv(2048)
newthread = ClientThread(ip,port)
newthread.start()
threads.append(newthread)
list_data.append(data)
for t in threads:
t.join()
client1 code:
import socket
import RPi.GPIO as GPIO
import time
host = '192.168.0.198'
port = 9050
BUFFER_SIZE = 2000
MESSAGE = input("tcpClient1: Enter message/ Enter exit:")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while MESSAGE != 'exit':
s.send(str.encode(MESSAGE))
data = s.recv(BUFFER_SIZE)
data = data.decode('utf-8')
print (" Client2 received data:", data)
MESSAGE = input("tcpClient2: Enter message to continue/ Enter exit:")
client2 code:
import socket
import RPi.GPIO as GPIO
import time
import socket
host = '192.168.0.198'
port = 9050
BUFFER_SIZE = 2000
MESSAGE = input("tcpClient2: Enter message/ Enter exit:")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while MESSAGE != 'exit':
s.send(str.encode(MESSAGE))
data = s.recv(BUFFER_SIZE)
data = data.decode('utf-8')
print (" Client received data:", data)
MESSAGE = input("tcpClient2: Enter message to continue/ Enter exit:")
when i run, i obtain:
in the server terminal:
Multithreaded Python server : Waiting for connections from TCP clients...
[+] New server socket thread started for 192.168.0.197:47012
Multithreaded Python server : Waiting for connections from TCP clients...
[+] New server socket thread started for 192.168.0.196:47886
Multithreaded Python server : Waiting for connections from TCP clients...
in client1 terminal:
tcpClient1: Enter message/ Enter exit:begin
in client2 terminal:
tcpClient2: Enter message/ Enter exit:begin
It seems like server didn't receive or send any data.
As #Hikke mentioned in his comment, your server receives at two different places. The conn.recv call in this code snippet eats up the data that the server receiving thread is expecting. Remove data = conn.recv(2048) in your server's main loop:
while True:
print ("Multithreaded Python server : Waiting for connections from TCP clients...")
(conn, (ip,port)) = s.accept()
data = conn.recv(2048) # <== dont eat the data of your thread here!
newthread = ClientThread(ip,port)
newthread.start()
threads.append(newthread)
list_data.append(data)

Resources