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?
Related
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()
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?
I am learning python asyncio module and try to write a socks5 server with it. Python docs said:
Called when some data is received. data is a non-empty bytes object
containing the incoming data.
I wonder when client sends 2 bytes data, will data_received(self, data) just receive 1 byte not 2 bytes when it called and the rest 1 byte will call data_received(self, data) again?
#!/usr/bin/env python3
import asyncio
import logging
import socket
import struct
logging.basicConfig(level=logging.DEBUG,
format='{asctime} {levelname} {message}',
datefmt='%Y-%m-%d %H:%M:%S',
style='{')
class Remote(asyncio.Protocol):
def connection_made(self, transport):
self.transport = transport
self.server_transport = None
def data_received(self, data):
self.server_transport.write(data)
class Server(asyncio.Protocol):
INIT, REQUEST, REPLY = 0, 1, 2
def connection_made(self, transport):
client_info = transport.get_extra_info('peername')
logging.info('connect from {}'.format(client_info))
self.transport = transport
self.state = self.INIT
def data_received(self, data):
if self.state == self.INIT:
if data[0] == 5:
amount = data[1] # Authentication amount
if 0 in data[2:]:
self.transport.write(b'\x05\x00')
self.state = self.REQUEST
else:
self.eof_received()
else:
self.eof_received()
elif self.state == self.REQUEST:
ver, cmd, rsv, addr_type = data[:4]
logging.info('addr type: {}'.format(addr_type))
if addr_type == 1: # ipv4
addr = socket.inet_ntoa(data[4:8])
elif addr_type == 3:
addr_len = data[4]
addr = data[5:5+addr_len]
else:
data = b'\x05\x08\x00\x01'
data += socket.inet_aton('0.0.0.0') + struct.pack('>H', 0)
self.transport.write(data)
logging.error('not support addr type')
self.eof_received()
port = struct.unpack('>H', data[-2:])[0]
logging.info('target: {}:{}'.format(addr, port))
asyncio.ensure_future(self.remote(addr, port))
self.state = self.REPLY
elif self.state == self.REPLY:
logging.info('start relay')
self.remote_transport.write(data)
async def remote(self, addr, port):
loop = asyncio.get_event_loop()
transport, _remote = await loop.create_connection(Remote, addr, port)
_remote.server_transport = self.transport
self.remote_transport = transport
bind_addr, bind_port = transport.get_extra_info('sockname')
data = b'\x05\x00\x00\x01'
data += socket.inet_aton(bind_addr) + struct.pack('>H', bind_port)
self.transport.write(data)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
server = loop.create_server(Server, '127.0.0.2', 1089)
loop.run_until_complete(server)
try:
loop.run_forever()
except KeyboardInterrupt:
server.close()
loop.run_until_complete(server.close())
loop.close()
no, data_received will receive as many bytes as are already received by the server. If you need to receive the first 3 bytes to handle the request, then you should implement some buffering in your Protocol to allow you to wait for the rest of the request to arrive before continuing.
It would typically look like this:
def __init__(self, …):
self._buffer = bytearray()
…
def data_received(self, data):
self._buffer += data
if self.state == self.INIT:
# here we need at least 3 bytes.
# if we don't have enough data yet, just wait for the next `data_received` call
if len(self._buffer) < 3:
return
header, self._buffer = self._buffer[:2], self._buffer[2:]
# parse authentication header, switch the state to REQUEST
elif self.state == self.REQUEST:
…
I'm trying to write a UDP server that echos data back using asyncore.dispatcher_with_send
The problem i have is that when i set the buffer and call self.send(self.buffer), it seems to call handle_close and closes the socket.
import asyncore, socket,
class Server(asyncore.dispatcher_with_send):
def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_DGRAM)
self.bind(('192.168.0.10', 1452))
self.buffer = ''
self.recvData = ''
def handle_close(self):
self.close()
def handle_read(self):
print self.recv(8192)
self.buffer ='a'
def handle_write(self):
if self.buffer != '':
sent = self.send(self.buffer)
self.buffer = self.buffer[sent:]
if __name__ == '__main__':
The_Server = Server()
asyncore.loop()
Any Ideas?
Thanks
The solution was to use sendto and to make sure the sendto address was explicit.
import asyncore, socket,
class Server(asyncore.dispatcher_with_send):
def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_DGRAM)
self.bind(('192.168.0.10', 1452))
self.buffer = ''
self.recvData = ''
def handle_close(self):
self.close()
def handle_read(self):
print self.recv(8192)
self.buffer ='a'
def handle_write(self):
if self.buffer != '':
sent = self.sendto(self.buffer,('192.168.0.9',1452))
self.buffer = self.buffer[sent:]
if __name__ == '__main__':
The_Server = Server()
asyncore.loop()
I am attempting to write a UDP chat system, but for some reason the listen() loop is not working and I can not figure out why.
import socket
import json
import landerdb
import threading
class PeerChat:
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
def listen(self):
while True:
msg = self.sock.recv(1024)
print msg
def main(self):
while True:
msg = raw_input("> ")
for x in self.db.find("nodes", "all"):
self.sock.sendto(msg, tuple(x['addr']))
def GetNodes(self):
self.sock.sendto("as", (self.brok_ip, self.brok_port))
with open("nodes", 'wb') as file:
msg, addr = self.sock.recvfrom(1024)
print msg
file.write(msg)
if __name__ == "__main__":
PeerChat().GetNodes()
threading.Thread(target=PeerChat().listen).start()
PeerChat().main()