- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
Latest commit
118 lines (96 loc) · 3.31 KB
/
Copy pathserver.py
File metadata and controls
118 lines (96 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
importos
importsys
importstruct
importsocket
importthreading
fromenumimportIntEnum
frommsgtypesimportMsgTypes
fromrandomimportrandint
MAX_DEVICES=255
iflen(sys.argv) >=3:
HOST=sys.argv[1]
try:
PORT=int(sys.argv[2])
except:
print("Invalid port '%s'!"% (sys.argv[2]))
sys.exit(1)
else:
HOST=input("Enter the address: ")
whileTrue:
try:
PORT=int(input("Enter the port: "))
break
except:
print("Invalid port!")
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connected_devices= []
n_devices=0
classDevice:
def__init__(self, conn):
self.conn=conn
self.username=""
self.connected=True
self.receive_data_t=threading.Thread(name="receive_data", target=self.receive_data)
self.receive_data_t.start()
defreceive_data(self):
globaln_devices
whileself.connected:
type_=ord(self.conn.recv(1))
iftype_==MsgTypes.CloseConnection:
self.connected=False
print("[{}:{}] Connection closed!".format(*self.conn.getpeername()))
self.conn.close()
fordeviceinconnected_devices:
ifnotdevice.connected:
continue
content="%s left the chat!\n"% (self.username)
packed_length=struct.pack("H", len(content))
device.conn.sendall(chr(MsgTypes.Notification).encode() +packed_length+content.encode())
n_devices-=1
eliftype_==MsgTypes.OpenConnection:
username_len=ord(self.conn.recv(1))
username=self.conn.recv(username_len).decode()
self.username="%s#%04d"% (username, randint(0, 9999))
self.connected=True
self.conn.sendall(chr(MsgTypes.UsernameSet).encode() +chr(len(self.username)).encode() +self.username.encode())
fordeviceinconnected_devices:
ifnotdevice.connected:
continue
content="%s joined the chat!\n"% (self.username)
packed_length=struct.pack("H", len(content))
device.conn.sendall(chr(MsgTypes.Notification).encode() +packed_length+content.encode())
print("[{}:{}] Connected with username {}".format(*self.conn.getpeername(), self.username))
n_devices+=1
eliftype_==MsgTypes.SendMsg:
msg=self.conn.recv(1024)
ifnotself.username:
continue
fordeviceinconnected_devices:
ifdevice.connected:
device.conn.sendall(chr(MsgTypes.RecvMsg).encode() +chr(len(self.username)).encode() +self.username.encode() +msg)
eliftype_==MsgTypes.SendCmd:
cmd_size=ord(self.conn.recv(1))
cmd=self.conn.recv(cmd_size).decode()
ifcmd=="NUsers":
self.conn.sendall(chr(MsgTypes.CmdOutput).encode() +chr(cmd_size).encode() +cmd.encode() +chr(n_devices).encode())
elifcmd=="UsersList":
msg=b""
fordeviceinconnected_devices:
ifnotdevice.connected:
continue
msg+=chr(len(device.username)).encode()
msg+=device.username.encode()
self.conn.sendall(chr(MsgTypes.CmdOutput).encode() +chr(cmd_size).encode() +cmd.encode() +chr(n_devices).encode() +msg)
else:
pass
defget_connections():
whileTrue:
conn, addr=sock.accept()
ifn_devices>=MAX_DEVICES:
conn.close()
connected_devices.append(Device(conn))
sock.bind((HOST, PORT))
sock.listen()
print("Listening on {}:{} PID={}".format(HOST, PORT, os.getpid()))
connections_t=threading.Thread(name="get_connections", target=get_connections)
connections_t.start()