Skip to content

Instantly share code, notes, and snippets.

@JeanRibes
Last active January 2, 2020 21:47
Show Gist options
  • Save JeanRibes/ea0613d731f5aaaa438c013feebc19d2 to your computer and use it in GitHub Desktop.
Save JeanRibes/ea0613d731f5aaaa438c013feebc19d2 to your computer and use it in GitHub Desktop.
broadcast python chat
from socket import socket, AF_INET, SOCK_DGRAM, IPPROTO_UDP, SOL_SOCKET, SO_BROADCAST, SO_REUSEPORT, SO_REUSEADDR
from threading import Thread
import sys
import readline
class NetworkListener(Thread):
def __init__(self, sock, run):
self.sock = sock
self.running=run
super().__init__()
self.daemon = True
self.nicknames = {}
def run(self):
while self.running:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
msg = data.decode('utf-8')
if msg[:6]=='/nick ':
self.nicknames[addr]=msg[6:]
print("\r{} is now known as {}".format(addr[0],
self.nicknames[addr]))
else:
print("\r[{}]: {}".format(self.nicknames.get(addr, addr[0]), msg))
print("> ", flush=True, end="")
if __name__=='__main__':
sock = socket(family=AF_INET, type=SOCK_DGRAM, proto=IPPROTO_UDP)
ipaddr="0.0.0.0"
if len(sys.argv)>1:
ipaddr = sys.argv[1]
print("Using interface {}".format(ipaddr))
sock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
sock.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sock.bind(("0.0.0.0", 2000))
sendsock = socket(family=AF_INET, type=SOCK_DGRAM, proto=IPPROTO_UDP)
sendsock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
sendsock.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
sendsock.bind((ipaddr, 2000))
running = True
print("you can view nicknames mapping with /ip")
print("\033[3mset your nickname\033[23m with \033[1m'/nick your_username'\033[0m")
disp = NetworkListener(sock, running)
disp.start()
print("> ", end="")
while running:
try:
msg = input()
print(
"\033[{}\033[1A\r{}".format(
len(msg),
len(msg)*" "
), end="", flush=True)
if msg[:3] == "/ip":
if msg[:4] == "/ip ":
inv_nick = {v: k for k, v in disp.nicknames.items()}
print("\r"+str(inv_nick.get(msg[4:].rstrip('\n'), 'no match')))
else:
print("\r"+str(disp.nicknames))
print("> ", end="", flush=True)
continue
if msg[:6] == "/tell ":
try:
dest = msg[6:].split(" ")[0]
msg_secret = msg[(6+len(dest)):]
print("\r"+msg_secret)
inv_nick = {v: k for k, v in disp.nicknames.items()}
addr = inv_nick.get(dest, None)
if addr is None:
addr = (dest, 2000)
print("sending to {}".format(addr))
sendsock.sendto(bytes(msg_secret, 'utf-8'), addr)
continue
except Exception as e:
print("\rnope, not sending")
print(e)
tosend = bytes(msg, "utf-8")
sendsock.sendto(tosend, ("192.168.0.255", 2000))
except (KeyboardInterrupt, EOFError):
running=False
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment