Bidirectional communication between respberry pi's via socket (python3) - python-3.x

I got 50% of this to work - pi #1 acts as the server and sends messages to the client (pi #2).
But how can it RECEIVE information back from the client?
Basically, the issue I'm having is that pi #1 needs to receive commands from pi #2 as well.
SERVER.py
import socket
import time
print("This is pizero2 as server.")
# REMOTE SETUP as SERVER
addresses = {
'littlechefee': {'ip': '192.168.39.242','port': 5003}, # pi4-one pi4 L wall .. liqs
}
sockets = []
i = 0
for addr in addresses:
ip = addresses[addr]['ip']
port = addresses[addr]['port']
sockets.append(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sockets[i].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sockets[i].connect((ip,port))
print(f'Success, connected with {addr}. ')
except:
print("Unable to Connect Rpi with IP: {} and Port: {}".format(ip,port ))
i += 1
def send():
command = 'test from pizero2'
indx = 0 # bc only 1 remote pi
print(f"Sending littlechefee a cmd.")
try:
sockets[indx].sendall(str(command).encode('utf-8'))
except:
print('Unable to send command! Invalid options')
while True:
send()
CLIENT.py
import socket
import time
# REMOTE SETUP as CLIENT
rcv_ip = '192.168.39.46' # Please insert the receiver own ip (ip of rpi on which this script is running.) Example : '192.268.xx.xx'
rcv_port = 5002 # please use 5001 upto 5006 for different rpi's
sock_rcv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_rcv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock_rcv.bind((rcv_ip,rcv_port))
sock_rcv.listen(10)
def get_data():
dt_r, adr_r = sock_rcv.accept()
while True:
cmd = dt_r.recv(1024)
if cmd:
cmd = cmd.decode('utf-8') # str = ['dispense', [13, 6, 13], 50]
cmd = cmd.split(' ') # lst = ["['dispense',", '[13,', '6,', '13],', '50]']
print("cmd is: ", cmd) # cmd = ["['nema',", "'W',", "'5',", '3000]']
else:
print("Connection closed.")
break
time.sleep(1)
while True:
get_data()

Related

be maked Infinite loop in python.3

i want to make one server and client in the python.3
this is my server:
import socket
ip =('192.168.1.101',12345)
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(ip)
s.listen(1)
print('Server is ready')
client , addr = s.accept()
print('one client has conected to me'+str(addr))
while True:
a = input('what do you want to tell ? ')
if a == 'q':
break
a=a.encode('utf_8')
client.sendall(a)
client.close()
and my client is :
import socket
ip = ('192.168.1.101', 12345)
conecttion = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conecttion.connect(ip)
while True:
data = conecttion.recv(1024)
if data == 'q':
break
print(data)
conecttion.close()
but when i send 'q' in the client be maked Infinite loop.
what should i to do when i send 'q' the conection be closed.
who can help me.
Two issues:
On the server, you are not sending 'q'. You are breaking before the send.
On the client, the received data is binary so you need to convert to a character.
Try this code:
Server:
import socket
ip =('127.0.0.1',12345) # local machine
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(ip)
s.listen(1)
print('Server is ready')
client , addr = s.accept()
print('one client has conected to me'+str(addr))
while True:
a = input('what do you want to tell ? ')
aa=a.encode('utf_8')
client.sendall(aa) # byte data
if a == 'q': # original string
break
client.close()
Client:
import socket, time
ip = ('127.0.0.1', 12345) # local machine
conecttion = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conecttion.connect(ip)
while True:
data = conecttion.recv(1024)
if data and chr(data[0]) == 'q':
break
print(data)
conecttion.close()

Python 3 socket client not connecting to server

I have a server.py and client.py pair. When I run the server on my machine and open multiple terminals to runs clients, I can connect fine. But when I try to run clients on another computer, the client never connects to the server. I'm pretty sure I tested this code a few months ago on multiple computers and it worked fine (though maybe I'm remembering wrong), but I think I updated my python version, so maybe that's why? How can I change my code below so it works?
server.py
import socket
from threading import Thread
import sys
clients = []
def recv(clientsocket):
while True:
msg = clientsocket.recv(1024) # wait for message from any of the clients.
print("\n" + msg.decode())
for c in clients: # send to all the clients.
c.send(msg)
def send(clientsocket):
while True:
msg = "[Server] %s" % input("\n") # wait for input
print(msg)
for c in clients: # send to all the clients.
c.send(msg.encode())
clientsocket.close()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create a socket object
host = socket.gethostname() # Get local machine name
#port = 3001 # Reserve a port for your service.
port = int(input("Enter port: "))
print ('Server started at [%s]' % socket.gethostbyname(host))
print ('Waiting for clients...')
#s.bind((host, port)) # Bind to the port
s.bind((socket.gethostbyname(host), port))
s.listen(5) # Now wait for client connection.
while True:
#Waits until someone new to accept
c, addr = s.accept()
print(addr, "connected.")
clients.append(c)
thread_recv = Thread(target=recv, args=((c,)))
thread_recv.start()
thread_send = Thread(target=send, args=((c,)))
thread_send.start()
s.close()
client.py
import socket
from threading import Thread
hostname = input("Enter hostname/IP to connect to: ")
# port = 3001
port = int(input("Enter port: "))
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect((hostname, port))
def recv():
while True:
print("\n" + clientsocket.recv(2048).decode())
def send(username):
while True:
msg = "[%s] %s" % (username, input(""))
clientsocket.send(msg.encode()) # send message to the server.
username = input("Choose a username: ")
msg = "[%s has just connected]" % (username)
clientsocket.send(msg.encode())
thread_send = Thread(target=send, args=(username,))
thread_send.start()
thread_recv = Thread(target=recv, args=())
thread_recv.start()
while True:
# keep the threads going.
pass
Edit
Every time I start the server, it says my ip address is the same: 192.168.56.1. Even though I've turned my computer off and tried again. But when I go to Google and ask what is my ip address, it is something totally different. Why does the socket keep choosing 192.168.56.1? Is there something special about it? Is this something related to my problem?
Just bind you server to 0.0.0.0 and bind it to all network interfaces:
server.py
s.bind(('0.0.0.0', port))
Then the code in server.py will end up being something like this:
import socket
from threading import Thread
import sys
clients = []
def recv(clientsocket):
while True:
msg = clientsocket.recv(1024) # wait for message from any of the clients.
print("\n" + msg.decode())
for c in clients: # send to all the clients.
c.send(msg)
def send(clientsocket):
while True:
msg = "[Server] %s" % input("\n") # wait for input
print(msg)
for c in clients: # send to all the clients.
c.send(msg.encode())
clientsocket.close()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create a socket object
host = socket.gethostname() # Get local machine name
#port = 3001 # Reserve a port for your service.
port = int(input("Enter port: "))
print ('Server started at [%s]' % socket.gethostbyname(host))
print ('Waiting for clients...')
#s.bind((host, port)) # Bind to the port
s.bind(('0.0.0.0', port))
s.listen(5) # Now wait for client connection.
while True:
#Waits until someone new to accept
c, addr = s.accept()
print(addr, "connected.")
clients.append(c)
thread_recv = Thread(target=recv, args=((c,)))
thread_recv.start()
thread_send = Thread(target=send, args=((c,)))
thread_send.start()
s.close()

s.recv hang in python sockets

I have a client and server machine.
From client I am sending a linux command which replies after 80 sec.
As the server does not reply initial80 seconds the (s.recv) and a timeout error occurs.
Please help how to proceed here?
s= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(300)
s.connect((hostname, self.port))
s.sendall(self.msg)) # where msg is some linux command or script which replies after 80 seconds
#s.shutdown(socket.SHUT_WR)
while 1:
data = s.recv(1024)
if data == b"":
break
datai = datai + data.decode()
self.result[hostname.decode()] = datai
I couldn't reproduce it. Here's server and client code that is almost what you have - it works as desired:
client:
#!/usr/bin/env python3
import socket #for sockets
import sys #for exit
try:
#create an AF_INET, STREAM socket (TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
sys.exit();
print 'Socket Created'
host = 'localhost'
port = 8888
try:
remote_ip = socket.gethostbyname( host )
except socket.gaierror:
#could not resolve
print 'Hostname could not be resolved. Exiting'
sys.exit()
print 'Ip address of ' + host + ' is ' + remote_ip
message = "The message \n"
#Code from Stackoverflow question
#s= socket.socket(socket.AF_INET, socket.SOCK_STREAM) # this is already done
s.settimeout(300)
#Connect to remote server
#s.connect((hostname, self.port)) # different variable name
s.connect((remote_ip , port))
print 'Socket Connected to ' + host + ' on ip ' + remote_ip
s.sendall(message) # where msg is some linux command or script which replies after 80 seconds
#s.shutdown(socket.SHUT_WR)
while 1:
data = s.recv(1024)
print("Ok, I get the response :)")
if data == b"":
break
datai = "DATAI: "
datai = datai + data.decode()
#self.result[hostname.decode()] = datai
print("Datai: " + str(datai))
#End
break
s.close()
server:
#!/usr/bin/env python3
'''
Simple socket server using threads.
Taken from: https://www.binarytides.com/python-socket-server-code-example/
'''
#Code for reproduce stackoverflow question
from time import sleep
#End
import socket
import sys
HOST = '' # Symbolic name, meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
while True:
#Receiving from client
data = conn.recv(1024)
#Code for reproduce stackoverflow question
print("Waiting 80secs...")
sec = 0
while(sec < 80):
sleep(10)
sec = sec + 10
print(str(sec))
print("Ok, I'll reply...")
#End
if not data:
reply = ""
else:
reply = 'OK...' + data
conn.sendall(reply)
break
conn.close()
s.close()

TCP server on raspberry pi not connecting to android tcp client on raspberry pi

I am creating a TCP server on raspberry pi so that i can control it from my android phone over WIFI. I have connected both the pi and the phone to my WIFI router.
import socket
from cookieLED_FINAL import callLED
host = '192.168.100.100'
port = 5560
def setupServer():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created.")
try:
s.bind((host, port))
except socket.error as msg:
print(msg)
print("Socket bind complete.")
return s
def setupConnection():
s.listen(1) # Allows one connection at a time.
conn, address = s.accept()
print("Connected to: " + address[0] + ":" + str(address[1]))
return conn
def storeFile(filePath):
picFile = open(filePath, 'wb')
print("Opened the file.")
pic = conn.recv(1024)
while pic:
print("Receiving picture still.")
picFile.write(pic)
pic = conn.recv(1024)
picFile.close()
def dataTransfer(conn):
# A big loop that sends/receives data until told not to.
while True:
# Receive the data
data = conn.recv(1024) # receive the data
data = data.decode('utf-8')
# Split the data such that you separate the command
# from the rest of the data.
dataMessage = data.split(' ', 1)
command = dataMessage[0]
if command == 'GET':
reply = GET()
elif command == 'REPEAT':
reply = REPEAT(dataMessage)
elif command == 'STORE':
print("Store command received. Time to save a picture")
storeFile(dataMessage[1])
print("FINISHED STORING FILE")
break
elif command == 'LED_ON':
callLED()
reply = 'LED was on'
elif command == 'EXIT':
print("Our client has left us :(")
break
elif command == 'KILL':
print("Our server is shutting down.")
s.close()
break
else:
reply = 'Unknown Command'
# Send the reply back to the client
conn.sendall(str.encode(reply))
print("Data has been sent!")
conn.close()
s = setupServer()
while True:
try:
conn = setupConnection()
dataTransfer(conn)
except:
break
When using IP:
192.168.100.100 :
[Errno 99] Cannot assign requested address
127.162.100.100 or 0.0.0.0: The socket is being created but android client is not getting connected.
On my android phone i am using an app named TCP/UDP Test Tool which I downloaded from play store.
I am new on linux as well as on raspberry pi 3 B+.
OS: RASPBIAN
PROGRAMMING LANGUAGE: PYTHON 3.5
Download a software named Advanced IP Scanner.
Connect all the devices to the same network i.e Access point.
On the raspberry pi open terminal and type ifconfig get the ipv4 not the 0.0.0.0 or the 127.0.0.1 the other one.
For example if the ip is showing 192.168.100.144 then input 192.168.100.1-255 in Advanced IP scanner in windows start the scan and find the ips that has your raspberry pi's name written in it. Now input these ips in the tcp client and connect.

Python UDP client-server with different matching incoming-outgoing ports

Based on the example at http://www.binarytides.com/programming-udp-sockets-in-python/ I modified it to run on python 3 and used two opposed ports on client and server, so replies from each one go to these ports. Here are my examples
Server:
'''
Simple udp socket server
'''
import socket
import sys
HOST = 'localhost'
PORT_IN = 8889 # Arbitrary non-privileged port
PORT_OUT = 8888
# Datagram (udp) socket
try :
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print('Socket created')
except socket.error as e:
print(e)
sys.exit()
# Bind socket to local host and port
try:
s.bind((HOST, PORT_IN))
except socket.error as e:
print(e)
sys.exit()
print('Socket bind complete')
#now keep talking with the client
while 1:
# receive data from client (data, addr)
d = s.recvfrom(1024)
data = d[0]
addr = d[1]
if not data:
break
reply = 'OK...' + str(data)
s.sendto(reply.encode('UTF-8'), ('localhost', PORT_OUT))
print('Message[' + addr[0] + ':' + str(addr[1]) + '] - ' + str(data).strip())
s.close()
Client:
'''
udp socket client
Silver Moon
'''
import socket #for sockets
import sys #for exit
# create dgram udp socket
try:
s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
print('Failed to create socket')
sys.exit()
host = 'localhost'
port_out = 8889
port_in = 8888
counter = 0
while(1) :
# msg = b'aoua'
msg = 'aoua' + str(counter)
try :
#Set the whole string
s1.sendto(msg.encode('UTF-8'), (host, port_out))
# receive data from client (data, addr)
s2.bind(('localhost', port_in))
d = s2.recvfrom(1472)
reply = d[0]
addr = d[1]
print('Server reply : ' + str(reply))
except socket.error as e:
print(e)
# sys.exit()
counter += 1
Problem is with the client which cannot receive any response from server and d = s2.recvfrom(1472) hangs with error [WinError 10022] An invalid argument was supplied.
I've noticed a slightly different behaviour with sock.settimeout(seconds), but I really can't figure why. Isn't d = s2.recvfrom(buffer) supposed to wait for incoming data?
What am I missing here?
Damn... Just saw it. Silly mistake. Calling s2.bind(('localhost', port_in)) in Client inside the loop.

Resources