-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
executable file
·86 lines (76 loc) · 3.52 KB
/
server.py
File metadata and controls
executable file
·86 lines (76 loc) · 3.52 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
#!/usr/bin/env python
"""
A chat server in Python.
Entering 'stop' at the terminal will exit the server.
"""
import select
import socket
import sys
class Server:
def __init__(self):
self.host = ''
self.port = 5000
self.backlog = 5
self.size = 1024
self.server = None
self.socket_connections = []
def open_socket(self):
try:
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind((self.host, self.port))
self.server.listen(self.backlog)
print 'Chat server started on port {port}'.format(port=self.port)
except socket.error, (error_code, message):
if self.server:
self.server.close()
print 'Could not open socket. Error code: {error_code} Message: {message}.'.format(error_code=error_code, message=message)
sys.exit(1)
def run(self):
self.open_socket()
self.socket_connections = [self.server, sys.stdin]
running = True
while running:
ready_to_read, ready_to_write, ready_to_except = select.select(self.socket_connections, [], [])
for s in ready_to_read:
# handle new client connections to the server
if s == self.server:
socket_obj, address = self.server.accept()
self.socket_connections.append(socket_obj)
print 'Client at {host}: {port} has connected.'.format(host=address[0], port=address[1])
self.broadcast(socket_obj, '\r{address} entered the chat room.\n'.format(address=address))
# handle standard input
elif s == sys.stdin:
cmd = sys.stdin.readline()
print 'Server received: {cmd}'.format(cmd=cmd)
print 'Stopping the server...'
running = False
# handle messages received from clients
else:
try:
data = s.recv(self.size)
if data.startswith('/quit'):
print 'Client {client_name} has disconnected.'.format(client_name=str(s.getpeername()))
self.broadcast(self.server, '\rClient {client_name} is offline'.format(client_name=str(s.getpeername())))
s.close()
self.socket_connections.remove(s)
elif data:
self.broadcast(s, '\r[{client_name}]: {message}'.format(client_name=str(s.getpeername()), message=data))
# Unless the client disconnected by itself
except socket.error, (error_code, message):
print 'Could not read from socket. Error code: {error_code} Message: {message}.'.format(error_code=error_code, message=message)
s.close()
self.socket_connections.remove(s)
self.server.close()
def broadcast(self, origin_socket, message):
for s in self.socket_connections:
# send the message only to other clients
if s is not self.server and s is not sys.stdin and s is not origin_socket:
try:
s.send(message)
except Exception:
s.close()
self.socket_connections.remove(s)
if __name__ == '__main__':
s = Server()
s.run()