I made an app to send to python socket the message "Oleft" when i tilt the phone but the result on console is like:
connection from('192.168.0.101', 33313)
b'Oleft'
b'OleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleft'
b'Oleft'
b'OrightOrightOrightOright'
b'OleftOleftOleftOleftOleftOrightOrightOrightOrightOrightOrightOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleft'
b'OleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleft'
b'OleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleft'
b'OleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleft'
b'OleftOleft'
It has no way to receive only an b'Oleft' ?
wgremote.py
import socket
class WGRemote:
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.host = socket.gethostname()
self.port = 10000
self.received = None
def connect(self):
global c, addr
self.sock.bind((self.host, self.port))
self.sock.listen(5)
c, addr = self.sock.accept()
print('connection from' + str(addr))
def setMode(self,mode):
sent = c.send(mode.encode("utf-8"))
def receive(self):
self.received = c.recv(1024)
return self.received
def close(self):
c.close
testApp.py
import socket
import sys
from wgremote import WGRemote
remote = WGRemote()
remote.connect()
remote.setMode('orient')
while True:
data = remote.receive()
print(data)
Because, You wrote print(data) in the while loop :)
while True:
data = remote.receive()
print(data)
If you want to receive only an b'Oleft you can make a filter :
count = 0
while True:
data = remote.receive()
if data == "b'Oleft":
if count < 1:
count = count + 1
print(data)
Or you must send the only an b'Oleft :)
Related
I am trying to simply send messages from two client sockets to one server socket. When I start up the server socket, it works fine, and then when I start up each of the two client sockets (I'm using 3 different terminal windows) everything works fine. If I start up the server and one client, I can send messages from the client to the server. If I then start up the second client, I can send messages from the second client to the server, however now if I go back and try to send messages from the first client to the server, I get a " BlockingIOError: [Errno 11] Resource temporarily unavailable ". What is the problem?
clientclass.py:
from itertools import count
import select
import random
import threading
import time
class Client(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.host = "127.0.0.1"
self.port = 65432
def run(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.id = random.randrange(0, 1000)
print(f"client id {self.id} connected")
self.sock.connect((self.host, self.port))
while True:
text = input('m: ')
self.sock.sendall(text.encode())
server.py:
import socket
from itertools import count
import select
from _thread import start_new_thread
import threading
import time
from queue import Queue
class server(threading.Thread):
def __init__(self):
self.host = "127.0.0.1"
self.port = 65432
threading.Thread.__init__(self)
def run(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))
self.sock.listen(5)
self.sock.setblocking(0)
print(f"server instantiated")
inputs = [self.sock]
outputs = []
message_queues = {}
while inputs:
inputready,outputready,exceptready = select.select(inputs,outputs,inputs)
for input_item in inputready:
if input_item is self.sock:
conn, addr = self.sock.accept()
print("New connection from: ", addr)
conn.setblocking(0)
inputs.append(conn)
else:
data = conn.recv(1024)
if data:
print("Client: " + data.decode())
#message_queues[input_item].put(data)
if input_item not in outputs:
outputs.append(input_item)
else:
if input_item in outputs:
outputs.remove(input_item)
inputs.remove(input_item)
input_item.close()
class Message_Sender(threading.Thread):
def __init__(self, client):
threading.Thread.__init__(self)
self.client = client
def run(self):
while True:
text = input('m: ')
server.conn.sendall(text.encode())
server = server()
server.start()
msg = Message_Sender(server)
msg.start()
client instances:
import clientclass
client = clientclass.Client()
client.start()
I saw your code and I think I have solved the problem you might have
I changed some code In a way It receives multiple clients at the same time
server.py:
import socket
from itertools import count
import select
from _thread import start_new_thread
import threading
import time
from queue import Queue
class server(threading.Thread):
def __init__(self):
self.host = "127.0.0.1"
self.port = 65432
threading.Thread.__init__(self)
def run(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))
print(f"server instantiated")
inputs = [self.sock]
outputs = []
message_queues = {}
while True:
self.sock.listen(5)
conn, addr = self.sock.accept()
receive = threading.Thread(target=self.receive_data, args=(conn,))
receive.start()
inputs.append(conn)
def receive_data(self, conn):
while True:
data = conn.recv(1024)
if data:
print("Client: " + data.decode())
# do something
class Message_Sender(threading.Thread):
def __init__(self, client):
threading.Thread.__init__(self)
self.client = client
def run(self):
while True:
text = input('m: ')
server.conn.sendall(text.encode())
server = server()
server.start()
msg = Message_Sender(server)
msg.start()
I have made a loop inside the run function, when someone tries to connect it will make a new thread to receive their messages. it wasn't clear to me what you wanted to do with the variables inputs and input_item, ect. but I think you can get really far with this. If you still have any problems feel free to reach out.
I am writing a code where an arduino reads data from an accelerometer, passes it to a python script and then that computer running python sends the data to another computer over a socket conneciton. I have written code which can send and recieve one message at a time, slowly, but as soon as I do it bascially as fast as I can (about 100Hz) then the server side only prints the first message, but no more.
Here is the code for my server side:
import socket
class server:
def __init__(self, PORT=9077, MAX_CONNECTIONS=1000, BUFF_SIZE=1024):
self.s = socket.socket()
self.HOST = socket.gethostbyname(socket.gethostname())
self.PORT = PORT
self.MAX_CONNECTIONS = MAX_CONNECTIONS
self.BUFF_SIZE = BUFF_SIZE
self.s.bind((self.HOST, self.PORT))
self.s.listen(self.MAX_CONNECTIONS)
self.recievingData = False
print("Starting a server")
print("IP: " + str(self.HOST))
print("Port: " + str(self.PORT))
def recieveData(self):
self.recievingData = True
while self.recievingData:
print("Waiting for data")
c, addr = self.s.accept()
print(addr)
data = b''
part = c.recv(self.BUFF_SIZE)
data += part
while len(part) > self.BUFF_SIZE:
# print("looping")
part = c.recv(self.BUFF_SIZE)
print(len(part))
data += part
print(data)
c.close()
def stopRecieving(self):
self.revievingData = False
new_server = server()
new_server.recieveData()
and the client side:
class client:
def __init__(self, HOST="192.168.0.51", PORT=9077):
self.s = socket.socket()
self.HOST = HOST
self.PORT = PORT
self.s.connect((self.HOST, self.PORT))
def send_message(self, message):
message = message.encode()
sent = self.s.sendall(message)
print(sent)
and I basically just call send_message every time there is new data to send.
Is there a way to increase the speed at which the server can recieve messages from the same client? Do I need to create multiple threads for recieving data?
My solution to this was using DTP protocol, where you send messages without checking if the data has been recieved. This is achieved using socket.socket(type=SOCK_DGRAM) on the client and server side and using self.s.recvfrom(self.BUFF_SIZE) for recieving data from a client and self.s.sendto(str(message).encode(), (host, port)) for sending data. This way, there is no handshake between the client and the server and it runs much faster.
You just need some error checking from your input data.
For reference, this is my full updated code:
import socket
from socket import SOCK_DGRAM, SO_REUSEADDR
import numpy as np
import threading
class client:
def __init__(self, HOST="192.168.0.51", PORT=9077):
self.s = socket.socket(type=SOCK_DGRAM)
self.HOST = HOST
self.PORT = PORT
def send_message(self, message):
self.s.sendto(str(message).encode(), (host, port))
class server:
def __init__(self, PORT=9077, BUFF_SIZE=1024):
self.s = socket.socket(type=SOCK_DGRAM)
self.HOST = socket.gethostbyname(socket.gethostname())
self.PORT = PORT
self.MAX_CONNECTIONS = MAX_CONNECTIONS
self.BUFF_SIZE = BUFF_SIZE
self.s.bind((self.HOST, self.PORT))
# self.s.listen(self.MAX_CONNECTIONS)
self.recievingData = False
self.recievedData = np.zeros((1,4))
self.thread = threading.Thread(target=self.recieveData)
self.thread.start()
# self.s.setblocking(0)
self.startRecieving()
print("Starting a server")
print("IP: " + str(self.HOST))
print("Port: " + str(self.PORT))
def startRecieving(self):
self.recievingData = True
self.recievedData = np.zeros((1,4))
self.thread = threading.Thread(target=self.recieveData)
self.thread.start()
print("Started reading data")
def stopRecieving(self):
self.recievingData = False
self.thread.join()
print("Stopped reading data")
def recieveData(self):
self.recievingData = True
while self.recievingData:
# print("Waiting for data")
part, addr = self.s.recvfrom(self.BUFF_SIZE)
# print(part, addr)
data = b''
data += part
while len(part) > self.BUFF_SIZE:
# print("looping")
part = self.s.recvfrom(self.BUFF_SIZE)
# print(len(part))
data += part
self.lastData = data
print(data)
as_float = np.array([[float(x.strip()) for x in data.decode().split(',')]])
self.recievedData = np.vstack((self.recievedData, as_float))
this is my client:
import socket
import threading
class ThreadedServer(object):
def __init__(self, host, port):
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))
def listen(self):
self.sock.listen(5)
while True:
client, address = self.sock.accept()
client.settimeout(60)
threading.Thread(target = self.listenToClient,args = (client,address)).start()
def listenToClient(self, client, address):
size = 1024
while True:
try:
data = client.recv(size)
if data:
# Set the response to echo back the recieved data
response = data
client.send(response)
else:
raise error('Client disconnected')
except:
client.close()
return False
if __name__ == "__main__":
ThreadedServer('',5000).listen()
I'm trying parse the message received. I have tried the following:
if data:
if data == "command":
print("Command Received")
elif data != "command":
response = data
client.send(response)
else:
raise error('Client disconnected')
I have printed data to console and it comes out as b'command', I have tried using that in the equal to string and it still does not print 'Command receieved' when I send it from my client which just connects to the server and sends a message doing the following mySocket.send(message.encode()) I was wondering how I could fix my issue?
Just found the solution: you have to decode the UDP message when printing it.
Example:
print data.decode()
I'm implementing a simple messaging application using Python. I've defined a client CClient which instantiates a CMsgGateway and then begins a thread which asks the user for input (while 1). The client is as follows:
from msginterface import CMsgGateway
class CClient():
def __init__(self):
self.port = 2400
self.msgGate = CMsgGateway(self.port)
Thread(target=self.inputMsg).start()
def inputMsg(self):
while 1:
msg = input("Enter message:")
self.msgGate.sendMsg(msg)
if __name__ == '__main__':
cmdchat = CClient()
The message gateway listens for messages being received in a separate thread (while 1). This class is defined as:
from threading import Thread
import socket, struct, sys
class CMsgGateway():
def __init__(self, port):
self.port = port
print("Listening on port " + str(self.port) + ".\n")
Thread(target=self.serve).start()
def serve(self):
while 1:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(("", self.port))
self.sock.listen(1)
self.rcvMsg()
def rcvMsg(self):
serverSocket, info = self.sock.accept()
while 1:
try:
buf = bytearray(4000)
view = memoryview(buf)
bytes = serverSocket.recv_into(view, 4000)
if bytes:
stx = view[0]
Size = view[1:3]
bSize = Size.tobytes()
nTuple = struct.unpack(">H", bSize)
nSize = nTuple[0]
message = view[0:3+nSize]
messageString = message.tobytes().decode("utf-8").strip()
print("Received message:\n\n" + messageString)
sys.stdout.flush()
else:
break
except socket.timeout:
break
def sendMsg(self, msgToSend):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host = socket.gethostname()
self.sock.connect((host, self.port))
self.sock.send(msgToSend.encode())
self.sock.close()
When I run the program the thread within CMsgGateway begins, listening for messages. However, as far as I can tell the thread within CClient, the inputMsg method, does not begin (I see no prompt to enter input e.g. "Enter message" is not displayed).
Could someone please help me figure out what is wrong with this? Many thanks.
I am trying to create a chat program that works by UDP hole punching and connecting directly to a node which is provided by a broker.
The script I have right now works just fine locally. The problems come when I try to use an external address to connect to. I can't figure this out on my own so I was hoping someone here could help me out!
import socket
import json
import landerdb
import threading
class PeerChat:
address = None
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.db = landerdb.Connect("nodes")
self.brok_ip = ""
self.brok_port = 5000
self.nick = "Test"
self.friends = []
def listen(self):
self.command = {
"HERE":self.here,
"MSG":self.msg,
}
global address
self.sock.bind(address)
while True:
msg, addr = self.sock.recvfrom(1024)
try:
data = json.loads(msg)
except:
continue
if data[u'cmd'] in self.command:
threading.Thread(target=self.command[data[u'cmd']], args=(addr, data)).start()
def main(self):
while True:
msg = raw_input("> ")
msg = msg.split()
try:
msg = json.dumps({"cmd":msg[0], "data":' '.join(msg[2:]), "nick":self.nick, "to":msg[1]})
except:
continue
for x in self.db.find("nodes", "all"):
self.sock.sendto(msg, tuple(x['addr']))
def here(self, addr, data):
if not self.db.find("nodes", {"addr":addr}):
self.db.insert("nodes", {"addr":addr})
if data['nick'] in self.friends:
print data['nick'] + " has come online."
def msg(self, addr, data):
if data['to'] == self.nick:
print data['nick']+": "+data['data']
def GetNodes(self):
self.sock.sendto("", (self.brok_ip, self.brok_port))
with open("nodes", 'wb') as file:
while True:
msg, addr = self.sock.recvfrom(1024)
if msg == "\n":
break
file.write(msg)
msg, addr = self.sock.recvfrom(1024)
global address
address = ("0.0.0.0", int(msg))
for x in self.db.find("nodes", "all"):
addr = tuple(x['addr'])
self.sock.sendto(json.dumps({"cmd":"HERE", "nick":self.nick}),addr)
if __name__ == "__main__":
PeerChat().GetNodes()
threading.Thread(target=PeerChat().listen).start()
PeerChat().main()
I haven't tested this code externally yet, because I'm at uni, but I use slightly different lines to setup a UDP connection.
They might give you some ideas...
#!/usr/bin/python
import socket
import struct
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('239.255.60.60', 4876))
mreq = struct.pack("=4sl", socket.inet_aton("239.255.60.60"), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
packet_number = 0
while True:
packet_number += 1
print packet_number
raw_data = sock.recv(1024)
print raw_data
print
I don't fully understand all that, but it works for me.
It was adapted from here. You should read the entire page a couple of times to understand what they are saying. Do a search of the page for 'IP_MULTICAST_TTL' I gather that you need to set socket.IP_MULTICAST_TTL, 33 in sock.setsockopt, where the number is any number > 32. Remember that I am almost as unsure as you are at this stage...