Mouse remote control - python

Trying to implement some kind of synergy on python using PyAutoGui and socket communication.
The idea is to control mouse and keyboard of another computer on LAN by using mouse/keyboard of a server computer.
By now it's only mouse movement implementaion.
Here are some classes:
Server part:
class Server:
def __init__(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.ip = get_ip()
self.port = 3000
self.transfer_mod = False
self.client_address = ""
def start(self):
print("Started server with ip: {}".format(self.ip))
self.s.bind((self.ip, self.port))
self.get_connection()
def get_connection(self):
print("Waiting for connection...")
while True:
request, self.client_address = self.s.recvfrom(4096)
if request:
self.s.sendto(request, self.client_address)
print("{} connected!".format(self.client_address))
break
def enable_transfer(self):
print("Transfer to {} enabled".format(self.client_address))
self.transfer_mod = True
transfer_thread = threading.Thread(target=self.transfer_mouse)
transfer_thread.start()
def disable_transfer(self):
print("Transfer to {} disabled".format(self.client_address))
self.transfer_mod = False
def transfer_mouse(self):
previous_pos = (-1, -1)
while self.transfer_mod:
pos = pyautogui.position()
if pos != previous_pos:
data = pickle.dumps(pos)
self.s.sendto(data, self.client_address)
sleep(0.1)
previous_pos = pos
def close(self):
self.disable_transfer()
self.s.close()
Client part:
class Client:
def __init__(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.port = 3000
self.connection = False
def connect(self, server_ip):
request = bytes("Request","utf-8")
self.s.sendto(request, (server_ip, self.port))
received, address = self.s.recvfrom(4096)
if received == request:
print("Connected to {}".format(server_ip))
self.connection = True
threading.Thread(target=self.receive_data).start()
def receive_data(self):
while self.connection:
data, server = self.s.recvfrom(4096)
pos = pickle.loads(data)
self.control_mouse(pos)
def disconnect(self):
print("Disconnected from the server")
self.connection = False
def control_mouse(self, position):
pyautogui.moveTo(position[0], position[1])
def close(self):
self.disconnect()
self.s.close()
So, the problem of that is the speed of mouse movement on client computer is so low. It seems there are too many exceed packets or something like that. So, the question itself: Is it a good way of implementing this idea, if yes, what's the problem of that script, if no, any advises on how to do it more properly?

Related

How to put packet in socket

How to put packet in socket, when I use socket.recv? I made my TCP server to client network. But in the code, I want to put packet in self.soc.recv(1024). How can I put the packet in socket?
Here's my code
#서버 코드
import threading, socket
class Room: #채팅방
def __init__(self):
self.clients = []#접속한 클라이언트를 담당하는 ChatClient 객체 저장
def addClient(self, c):#클라이언트 하나를 채팅방에 추가
self.clients.append(c)
def delClent(self, c):#클라이언트 하나를 채팅방에서 삭제
self.clients.remove(c)
def sendAllClients(self, msg):
for c in self.clients:
c.sendMsg(msg)
class ChatClient:#텔레 마케터: 클라이언트 1명이 전송한 메시지를 받고, 받은 메시지를 다시 되돌려줌
def __init__(self, id, soc, r):
self.id = id #클라이언트 id
self.soc = soc #담당 클라이언트와 1:1 통신할 소켓
self.room = r #채팅방 객체
def recvMsg(self):
while True:
data = self.soc.recv(1024)
msg = data.decode()
if msg == '/stop':
self.sendMsg(msg) # 클라이언트쪽의 리시브 쓰레드 종료하라고..
print(self.id,'님 퇴장')
break
msg = self.id+': ' + msg
self.room.sendAllClients(msg)
self.room.delClent(self)
self.room.sendAllClients(self.id+'님이 퇴장하셨습니다.')
def sendMsg(self, msg): #담당한 클라이언트 1명에게만 메시지 전송
self.soc.sendall(msg.encode(encoding='utf-8'))
def run(self):
t = threading.Thread(target=self.recvMsg, args=())
t.start()
class ServerMain:
ip = '192.168.55.232'
port = 2500
def __init__(self):
self.room = Room()
self.server_soc = None
def open(self):
self.server_soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server_soc.bind((ServerMain.ip, ServerMain.port))
self.server_soc.listen()
def run(self):
self.open()
print('채팅 서버 시작')
while True:
c_soc, addr = self.server_soc.accept()
print(addr)
msg = '사용할 id:'
c_soc.sendall(msg.encode(encoding='utf-8'))
msg = c_soc.recv(1024)
id = msg.decode()
cc = ChatClient(id, c_soc, self.room)
self.room.addClient(cc)
cc.run()
print('클라이언트', id, '채팅 시작')
def main():
server = ServerMain()
server.run()
main()
I got my packet by wireshark, and I want put packet in soket.recv(). Is any solution that I can get?

Server is sending quicker than client can recv

my server sends objects much faster than the client receives. That's why the client receives the objects that were sent 10 seconds ago because the client has to receive every object that is in the queue. So my question is: How do I slow the server down or make my client receiving faster?
Edit: I added time.sleep(0.1) to the server but is there a more efficient way?
This is my Network class:
import socket
import pickle
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "192.168.1.15"
self.port = 5555
self.addr = (self.server, self.port)
self.player = self.connect()
def get_player(self):
return self.player
def connect(self):
try:
self.client.connect(self.addr)
except:
pass
def send_object(self, data):
self.client.send(pickle.dumps(data))
def get_object(self):
return pickle.loads(self.client.recv(1024))
def send_msg(self, data):
self.client.send(bytes(data, "utf-8"))
def get_msg(self):
return self.client.recv(1024).decode("utf-8")
and my server when it's sending:
p_count = conn.recv(1024).decode("utf-8")
if p_count:
games.append(Game(game_id, int(p_count), ip))
game_id += 1
while True:
conn.send(pickle.dumps(games[-1]))
and my client when it's receiving:
def update(self):
global bg_surface
try:
self.game = n.get_object()
self.player_in = self.game.players_ready
bg_surface = pygame.image.load('./bilder/background3.jpg').convert()
bg_surface = pygame.transform.scale(bg_surface, (screen_width, screen_height))
self.warte_text = Label(f"Warte auf Spieler {self.player_in}/{self.player_amount}", 20, (screen_width // 2, screen_height // 2 * 0.25), (255, 0, 0))
self.warte_text.update(bg_surface)
except:
pass
The efficient way to handle this is to have your server call select() or poll() on the socket to find out when the socket has room in its outgoing-data-buffer (and optionally block until there is room) and only generate and send() data to the socket when the socket has indicated it is ready-for-write. That way your server-thread doesn't get blocked waiting for the client to read data, no matter how slow the client is at reading.

Socket does not return any clients

I'm trying to build a socket and I want to print an object of clients, but for some reason whenever I connect it just returns empty {}
I'm new to Python and would like some insight
import socket
from threading import Thread
from multiprocessing import Process
import time as t
previousTime = t.time()
clients = {}
hostAddr = "127.0.0.1"
hostPort = 80
class sClient(Thread):
def __init__(self, socket, address):
Thread.__init__(self)
self.sock = socket
self.addr = address
self.start()
def run(self):
print("\nClient Connected from {}!".format(self.addr[0]))
self.sock.sendall("Welcome master".encode())
class sHost():
def __init__(self, host, port, clients):
self.sHost = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sHost.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sHost.bind((host, port))
self.sHost.listen()
self.start_listening()
def start_listening(self):
while 1:
clientSocket, clientAddr = self.sHost.accept()
clients[clientSocket.fileno()] = clientSocket
sClient(clientSocket, clientAddr)
def SendMsgToAllClients(msg):
print(clients) # this is empty
for client in clients.values():
try:
client.sendall(msg.encode())
except Exception as e:
print("Client probably disconnected, removing...")
finally:
del clients[client.fileno()]
if __name__ == '__main__':
Process(target=sHost, args=(hostAddr, hostPort, clients)).start()
print("Server is running")
while 1:
if previousTime + 3 <= t.time():
SendMsgToAllClients("Test")
previousTime = t.time()

Python Socket - Can't connect a second time

I have set up a socket server with a client and a host.
It works fine until the client has disconnected, with both .shutdown() and .close().
When I then launch the client again, it can't connect.
I presume this is not because of how I've written my code but rather what I haven't written.
How do I make the server truly disconnect the client's connection so that it can connect again?
Server:
import socket, threading, time, json
ONLINE_USERS = []
SESSION = None
class User():
def __init__(user, connection, address):
print('for', address, '{Connection established}')
user.connection = connection
user.address = address
user.character = None
threading.Thread(target=user.process, args=(), daemon=True).start()
def process(user):
time.sleep(1)
user.send("&pLogin\n^^^^^\n")
username = user.send("&iUser>")
password = user.send("&iPass>")
print(user.ping())
print(user.logout())
def send(user, *x):
user.connection.sendall(str.encode(str(x)))
data = user.connection.recv(1024)
return data if data!=b'\x01' else True
def recv(user, x):
user.connection.recv(x)
def ping(user):
start = time.time()
user.connection.sendall(b'\x02')
end = float(user.connection.recv(1024))
return round((end - start) * 1000)
def logout(user):
user.connection.sendall(b'\x04')
return user.connection.recv(4)
class Session():
def __init__(session, host='', port=12345):
session.host = host
session.port = port
session.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
session.socket.bind((host, port))
session.socket.listen(10)
def accept():
conn = User(*session.socket.accept())
session.thread_accept = threading.Thread(target=accept, args=(), daemon=True).start()
def shutdown():
for user in ONLINE_USERS.keys():
ONLINE_USERS[user].connection.sendall(bytes([0xF]))
if __name__ == '__main__':
SESSION = Session()
input('Press heart to continue!\n')
Client:
import socket, sys, threading, time, os
def clear(t=0.5):
time.sleep(t)
os.system('cls')
def tryeval(x, default):
try:
return eval(x)
except:
return default
class Client():
def __init__(client):
try:
server_info = input('IP_ADDRESS:PORT>').split(':')
client.host = server_info[0]
client.port = int(server_info[1])
except:
client.host = 'localhost'
client.port = 12345
client.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.socket.settimeout(10)
try:
client.socket.connect((client.host, client.port))
clear()
client.data_exchange()
finally:
client.shutdown()
def data_exchange(client):
while True:
data = client.socket.recv(1024)
if data:
if data==b'\x02':
client.socket.sendall(str.encode(str(time.time())))
elif data==b'\x04':
client.shutdown()
else:
data = tryeval(data, ())
response = []
for item in data:
try:
prefix, content = item[:2], item[2:]
if prefix=='&p':
print(content, end='')
elif prefix=='&i':
response.append(input(content))
if prefix=='&c':
time.sleep(float(content))
clear()
except:
pass
if len(response)>0:
client.socket.sendall(str.encode(str(tuple(response))))
else:
client.socket.sendall(b'\x01')
time.sleep(0.001)
def shutdown(client):
try:
client.socket.sendall(b'\x04')
except:
pass
print('Shutting down program.')
client.socket.shutdown(socket.SHUT_RDWR)
print('Socket has been shutdown.')
client.socket.close()
print('Socket has been closed.')
print('Exiting program')
time.sleep(1)
sys.exit()
if __name__ == '__main__':
client = Client()
"The server repeatedly calls accept waiting for new incoming connections." No it doesn't. It calls accept once in a thread...which exits. – Mark Tolonen

Python P2P Sockets Chat Script working only on home network (not on school network)

I have the following python script (a bit inefficient, I know) for a P2P chat program using sockets:
#!usr/bin/env python
import socket import threading import select import time import datetime
def main():
class Chat_Server(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.running = 1
self.conn = None
self.addr = None
def run(self):
HOST = ''
PORT = 23647
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST,PORT))
s.listen(1)
self.conn, self.addr = s.accept()
# Select loop for listen
while self.running == True:
inputready,outputready,exceptready \
= select.select ([self.conn],[self.conn],[])
for input_item in inputready:
# Handle sockets
message = self.conn.recv(1024)
if message:
print "Daniel: " + message + ' (' + datetime.datetime.now().strftime('%H:%M:%S') + ')'
else:
break
time.sleep(0)
def kill(self):
self.running = 0
class Chat_Client(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.host = None
self.sock = None
self.running = 1
def run(self):
PORT = 23647
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((self.host, PORT))
# Select loop for listen
while self.running == True:
inputready,outputready,exceptready \
= select.select ([self.sock],[self.sock],[])
for input_item in inputready:
# Handle sockets
message = self.sock.recv(1024)
if message:
print "Daniel: " + message + ' (' + datetime.datetime.now().strftime('%H:%M:%S') + ')'
else:
break
time.sleep(0)
def kill(self):
self.running = 0
class Text_Input(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.running = 1
def run(self):
while self.running == True:
text = raw_input('')
try:
chat_client.sock.sendall(text)
except:
Exception
try:
chat_server.conn.sendall(text)
except:
Exception
time.sleep(0)
def kill(self):
self.running = 0
# Prompt, object instantiation, and threads start here.
ip_addr = raw_input('Type IP address or press enter: ')
if ip_addr == '':
chat_server = Chat_Server()
chat_client = Chat_Client()
chat_server.start()
text_input = Text_Input()
text_input.start()
else:
chat_server = Chat_Server()
chat_client = Chat_Client()
chat_client.host = ip_addr
text_input = Text_Input()
chat_client.start()
text_input.start()
if __name__ == "__main__":
main()
This script works absolutely fine across a home network, with 192.168... internal IP addresses.
On a school network, with 172... IP addresses, it doesn't seem to work. There is no connection error, but messages are not sent or received, with the exception of if there are two instances of the application being run on the same computer with the same internal IP address, in which case the program works flawlessly.
I am very new to sockets and this sort of networking, so I am wondering if anyone can point out to me why this is the case. Might it be the difference in IP addresses, for example?
Thank you in advance.
I see you're connecting on port 23647 - you may not have access to this on your school network. Check if this port has traffic enabled. see: Port Forwarding for details.
Something like: this site/tool may allow you to check quickly.

Categories