i have a code which needs to perform the task of sending and receiving messages from specific clients. When i mention the client address in the send function of the server, i am being given a key error.
[NEW CONNECTION] ('10.14.0.1', 52870) connected.[ACTIVE CONNECTIONS] 1
Exception in thread Thread-3:
Traceback (most recent call last):
File "C:\Users\sho\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1009, in _bootstrap_inner
self.run()
File "c:\Users\sho\Documents\TcpCommExample\Server and clients\server 5.py", line 33, in run
clients["10.14.0.1"].send("VITA".encode(FORMAT))
KeyError: '10.14.0.1'
I have checked the dictionary by printing it and the client address does exist in it, i am not sure where i am making a mistake. Here is the code and any help would be tremendously appreciated.
import socket, threading
import time
HEADER = 80
PORT = 9000
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
VITA_POSITIVE = "0000"
my_timer = 0
class ClientThread(threading.Thread):
def __init__(self, conn: socket.socket, addr: str):
threading.Thread.__init__(self)
self.conn = conn
self.addr = addr
def send(self, msg: str):
self.conn.sendall(msg.encode())
def run(self):
print(f"[NEW CONNECTION] {self.addr} connected.")
connected = True
while connected:
clients["10.14.0.1"].send("VITA".encode(FORMAT))
vita_response_iconet = clients["10.14.0.1"].recv(HEADER).decode(FORMAT)
print(vita_response_iconet)
if vita_response_iconet == VITA_POSITIVE:
print("VITA received from Iconet")
vita_iconet = 1
else:
print("VITA not received from Iconet")
vita_iconet = 0
clients["10.14.0.1"].send("VITA".encode(FORMAT))
vita_response_robot = clients["10.14.0.1"].recv(HEADER).decode(FORMAT)
print(vita_response_robot)
if vita_response_iconet == VITA_POSITIVE:
print("VITA received from Robot")
vita_robot = 1
else:
print("VITA not received from Robot")
vita_robot = 0
if vita_iconet and vita_robot == 1:
my_timer = 0
else:
my_timer = my_timer
self.conn.close()
def countup():
global my_timer
for x in range(1, my_timer+1):
time.sleep(1)
countup_thread = threading.Thread(target=countup)
countup_thread.start()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
print('interesting')
print(conn)
print(addr)
thread = ClientThread(conn, addr)
print ('be ready')
thread.start()
clients[addr] = thread
print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 2}")
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
clients = {}
connections = threading.Thread(target=start)
connections.start()
print("[STARTING] server is starting...")
start()
You add to dictionary using
clients[addr] = thread
but addr is not "10.14.0.1" but ('10.14.0.1', 52870) and it sets
clients[ ('10.14.0.1', 52870) ] = thread
and you would have to use clients[ ('10.14.0.1', 52870) ] to access element in clients.
But there is other problem.
client keeps thread but you need connection/socket to run send() and recv() - so you have to use self.conn for this.
self.conn.send(...)
I didn't test it but it should be something like this
import socket
import threading
import time
# --- constants ---
HEADER = 80
PORT = 9000
#SERVER = socket.gethostbyname(socket.gethostname())
SERVER = '0.0.0.0'
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
VITA_POSITIVE = "0000"
# --- classes ---
class ClientThread(threading.Thread):
def __init__(self, conn: socket.socket, addr: str):
super().__init__()
self.conn = conn
self.addr = addr
def send(self, msg: str):
self.conn.sendall(msg.encode())
def run(self):
print(f"[NEW CONNECTION] {self.addr} connected.")
connected = True
while connected:
self.conn.send("VITA".encode(FORMAT))
vita_response_iconet = self.conn.recv(HEADER).decode(FORMAT)
print(vita_response_iconet)
if vita_response_iconet == VITA_POSITIVE:
print("VITA received from Iconet")
vita_iconet = 1
else:
print("VITA not received from Iconet")
vita_iconet = 0
self.conn.send("VITA".encode(FORMAT))
vita_response_robot = self.conn.recv(HEADER).decode(FORMAT)
print(vita_response_robot)
if vita_response_iconet == VITA_POSITIVE:
print("VITA received from Robot")
vita_robot = 1
else:
print("VITA not received from Robot")
vita_robot = 0
if vita_iconet and vita_robot == 1:
my_timer = 0
else:
my_timer = my_timer
self.conn.close()
# --- functions ---
def start():
try:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# solution for "[Error 89] Address already in use". Use before bind()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(ADDR)
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
print('wait for client')
conn, addr = server.accept()
print('interesting')
print(conn)
print(addr)
thread = ClientThread(conn, addr)
print ('be ready')
thread.start()
clients[addr] = thread
print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 2}")
except KeyboardInterrupt:
print('Stopped by Ctrl+C')
finally:
server.close()
# --- main ---
#my_timer = 0
clients = {}
# I don't know why you run it in thread and later run normally as `start()`
#connections = threading.Thread(target=start)
#connections.start()
print("[STARTING] server is starting...")
start()
Related
So I would like to have a variable as the socket server ip address... I have some issues. I get the issue with server.bind(ADDR)
import socket
import requests
import threading
def controller(conn, addr):
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNET:
connected = False
print(f'{msg}')
def start():
print('Server: Server Started')
server.listen()
while True:
conn, addr = server.accept()
thread = threading.Thread(target = controller, args = (conn, adrr))
thread.start()
host_name = socket.gethostname()
prip = socket.gethostbyname(host_name)
puip = requests.get('https://api.ipify.org').text
HEADER = 128
PORT = 5050
SERVER = puip
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNET = '!DISCONNECT'
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
start()
Error Message:
server.bind((SERVER, PORT))
OSError: [WinError 10049] The requested address is not valid in its context
When the disconnect message is received from my client(A django site sending the data), my socket isn't closing and this is preventing the rest of the code in my python file from running. If anybody knows what is causing this, help would be great.
My Code:
import threading
import queue
import socket
HEADER = 64
PORT = 6060
SERVER = '0.0.0.0'
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT!"
my_queue = queue.Queue()
print(SERVER)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected")
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
else:
my_queue.put(msg)
print(f"[{ADDR}] {msg}")
conn.send("MSG Received".encode(FORMAT))
conn.close()
def start():
server.listen()
print(f"[LISTENING] Server Is Listening On {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[Starting] Server")
start()
msg = my_queue.get()
print(msg)
I have written an online chess app, using Python and Sockets. When I run the server and connect the clients, everything runs perfectly smooth. However, when I convert the client into an exe file and run it, the client isn't able to connect to the server anymore.
I have also tried to convert the server into an executable and it stopped working either. I think it has problems with the command server.listen(), because the ouput is only [STARTING] Server is starting... (More details in the server side code below)
Has anybody encountered problems too, when converting a socket app into an exe file? I didn't get any results with a Google search.
Shortened client side code:
import socket
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
NONE_MESSAGE = "!NONE"
OPPONENT_DISCONNECTED = "!OPPONENT_DISCONNECTED"
SERVER = "192.168.56.1"
ADDR = (SERVER, PORT)
def send(client, msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
def recieve(client):
send(client, NONE_MESSAGE)
msg_length = client.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = client.recv(msg_length).decode(FORMAT)
if msg != NONE_MESSAGE:
return msg
return False
Server side code:
import socket
import threading
import random
HEADER = 64
PORT = 5050
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
NONE_MESSAGE = "!NONE"
OPPONENT_DISCONNECTED = "!OPPONENT_DISCONNECTED"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def recieve(conn):
send(conn, NONE_MESSAGE)
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg != NONE_MESSAGE:
return msg
return False
def send(conn, msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
conn.send(send_length)
conn.send(message)
def get_opponent(addr):
for c1, c2 in client_pairs:
if c1 == addr:
return c2
if c2 == addr:
return c1
return None
def handle_client(conn, addr):
global new_client
global new_client_name
name = recieve(conn)
if new_client:
print(f"[NEW CONNECTION] {addr} connected to {new_client}")
client_pairs.append((new_client, addr))
color = random.choice(['w', 'b'])
send(conn, color+new_client_name)
if color == 'w':
messages_to_send[new_client] = 'b'+name
else:
messages_to_send[new_client] = 'w'+name
new_client = None
new_client_name = None
else:
new_client_name = name
new_client = addr
print(f"[NEW CONNECTION] {addr} waiting")
connected = True
while connected:
if addr in messages_to_send.keys():
send(conn, messages_to_send[addr])
del messages_to_send[addr]
if addr in disconnects:
send(conn, OPPONENT_DISCONNECTED)
disconnects.remove(addr)
msg = recieve(conn)
if msg:
if msg == DISCONNECT_MESSAGE:
if new_client == addr:
new_client = None
opponent = get_opponent(addr)
if opponent:
disconnects.append(opponent)
connected = False
opponent = get_opponent(addr)
if opponent:
messages_to_send[opponent] = msg
print(f"[{addr}] {msg}")
conn.close()
new_client = None
new_client_name = None
messages_to_send = {}
client_pairs = []
disconnects = []
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount()-1}")
print("[STARTING] Server is starting...")
start()
Why does the client receive only when he has sent? When I start the server and connect two clients, they should be able to send messages to each other. They do, but only when they have currently sent a message to the server. This shouldn't be so, because the sending and recieving is in different threads.
Client side:
import socket
import threading
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
SERVER = "my local IP"
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
def events():
while True:
msg = input()
if msg == "quit":
send(DISCONNECT_MESSAGE)
break
else:
send(msg)
def receive():
while True:
msg_length = client.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = client.recv(msg_length).decode(FORMAT)
print(msg)
thread1 = threading.Thread(target=events)
thread2 = threading.Thread(target=receive)
thread1.start()
thread2.start()
Server side:
import socket
import threading
HEADER = 64
PORT = 5050
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
messages_to_send = {}
client_pairs = []
new_client = False
def send(msg, conn):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
conn.send(send_length)
conn.send(message)
def handle_client(conn, addr):
global new_client
if new_client:
print(f"[NEW CONNECTION] {addr} connected to {new_client}")
client_pairs.append((new_client, addr))
new_client = False
else:
print(f"[NEW CONNECTION] {addr} waiting")
new_client = addr
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
print(f"[DISCONNECTED] {addr}")
connected = False
if new_client == addr:
new_client = False
else:
for pair in client_pairs:
if addr == pair[0]:
if new_client:
client_pairs.append((new_client, addr))
new_client = False
else:
new_client = pair[1]
break
elif addr == pair[1]:
if new_client:
client_pairs.append((new_client, addr))
new_client = False
else:
new_client = pair[0]
break
else:
for pair in client_pairs:
if addr == pair[0]:
messages_to_send[pair[1]] = msg
elif addr == pair[1]:
messages_to_send[pair[0]] = msg
print(f"[{addr}] {msg}")
if addr in messages_to_send.keys():
send(messages_to_send[addr], conn)
del messages_to_send[addr]
conn.close()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"\n[ACTIVE CONNECTIONS] {threading.activeCount()-1}")
print("[STARTING] Server is starting...")
start()
Clients
import socket
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
SERVER = "192.168.1.105"
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(2048).decode(FORMAT))
send(DISCONNECT_MESSAGE)
Server
import socket
import threading
HEADER = 64
PORT = 5050
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[{addr}] {msg}")
conn.send("Msg received".encode(FORMAT))
conn.close()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting...")
start()
** So my idea is that I want to put the client file on my second computer and this client will take a screenshot
On each mouse click and then sends this img to the server and removes it from the second computer **
If anyone has a solution, please help me, and thank you.
notice : this for local connection