Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
U
uva
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Taddeüs Kroes
uva
Commits
36c82552
Commit
36c82552
authored
14 years ago
by
Sander Mathijs van Veen
Browse files
Options
Downloads
Patches
Plain Diff
Telematica: Almost finished client and server.
parent
bb7db307
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
telematica/ass1/async.py
+6
-4
6 additions, 4 deletions
telematica/ass1/async.py
telematica/ass1/server.py
+71
-15
71 additions, 15 deletions
telematica/ass1/server.py
with
77 additions
and
19 deletions
telematica/ass1/async.py
+
6
−
4
View file @
36c82552
...
...
@@ -77,6 +77,7 @@ class ClientConnection(object, AsyncBase, asyncore.dispatcher):
elif
chunk
==
'
\n
'
and
buf
[
-
1
]
==
'
\r
'
:
if
not
multi_line
:
break
self
.
debug_log
(
'
receiving multi line response...
'
)
if
buf
[
-
3
:]
==
'
\r\n\r
'
:
# Remove trailing '\n\r' from multi line response
buf
=
buf
[:
-
2
]
...
...
@@ -84,7 +85,7 @@ class ClientConnection(object, AsyncBase, asyncore.dispatcher):
buf
+=
chunk
buf
=
buf
[:
-
1
]
self
.
debug_log
(
'
< %s
'
%
buf
)
self
.
debug_log
(
'
< %s
'
%
buf
.
replace
(
'
\n
'
,
'
\\
n
'
).
replace
(
'
\r
'
,
'
\\
r
'
)
)
# Invoke the proper callback function.
if
not
self
.
verified
:
...
...
@@ -118,7 +119,7 @@ class ClientConnection(object, AsyncBase, asyncore.dispatcher):
if
not
self
.
authentification_sent
:
self
.
send_queue
.
put
(
'
USER %s
'
%
self
.
user
)
self
.
authentification_sent
=
True
elif
buf
[
1
:
9
]
==
'
Username
'
:
elif
buf
[
0
]
==
'
+
'
:
# TODO: handle 'username is taken'.
self
.
authenticated
=
True
if
'
authenticated
'
in
self
.
event_list
:
...
...
@@ -130,8 +131,9 @@ class ClientConnection(object, AsyncBase, asyncore.dispatcher):
# After authentification, fetch the list of users currently logged in.
if
not
self
.
retrieved_user_list
:
if
not
self
.
request_user_list_sent
:
self
.
request_user_list_sent
=
True
self
.
retrieve_users
()
#self.request_user_list_sent = True
#self.retrieve_users()
pass
else
:
# TODO: process user list
self
.
retrieved_user_list
=
True
...
...
This diff is collapsed.
Click to expand it.
telematica/ass1/server.py
+
71
−
15
View file @
36c82552
...
...
@@ -10,8 +10,10 @@ import sys
from
asyncbase
import
AsyncBase
# Greeting message sent to a connected client.
GREETING_MSG
=
'
Hi there!
'
# Major and minor version of this server.
MAJOR_VERSION
=
1
MINOR_VERSION
=
0
...
...
@@ -34,14 +36,13 @@ class Server(asyncore.dispatcher):
self
.
port
=
port
self
.
handler
=
handler
self
.
create_socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
logging
.
config
.
fileConfig
(
'
logging.conf
'
)
self
.
log
=
logging
.
getLogger
(
'
Server
'
)
# Listen on given ip-address and port
self
.
create_socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
set_reuse_addr
()
self
.
bind
((
ip
,
port
))
self
.
log
.
info
(
'
waiting for incoming connections on port %s.
'
%
port
)
self
.
listen
(
5
)
...
...
@@ -56,27 +57,54 @@ class Server(asyncore.dispatcher):
try
:
conn
,
addr
=
self
.
accept
()
self
.
log
.
info
(
'
accepted client %s:%d
'
%
addr
)
client
=
self
.
connect_client
(
addr
)
client
=
self
.
connect_client
(
conn
,
addr
)
except
socket
.
error
:
self
.
log
.
warning
(
'
warning: server accept() threw an exception.
'
)
return
except
TypeError
:
self
.
log
.
warning
(
'
warning: server accept() threw EWOULDBLOCK.
'
)
return
def
connect_client
(
self
,
conn
,
addr
):
"""
Initialise a client connection after the server accepted an incoming
connection. This will set the connection handler.
"""
client
=
ClientData
()
# creates an instance of the handler class to handle the
# request/response on the incoming connection.
self
.
handler
(
conn
,
addr
,
client
,
self
)
def
connect_client
(
self
,
addr
):
self
.
clients
[
'
%s:%d
'
%
addr
]
=
ClientData
()
return
self
.
clients
[
'
%s:%d
'
%
addr
]
client
.
handler
=
self
.
handler
(
conn
,
addr
,
client
,
self
)
client
.
username
=
''
self
.
clients
[
'
%s:%d
'
%
addr
]
=
client
return
client
def
disconnect_client
(
self
,
addr
):
del
self
.
clients
[
'
%s:%d
'
%
addr
]
"""
Client leaves the chat server. This function is called when the socket
is broken or the client closes the connection gracefully.
"""
# Suppress error if a client is already disconnected.
try
:
client
=
self
.
clients
[
'
%s:%d
'
%
addr
]
self
.
send_all
(
'
LEAVE %s
'
%
client
.
username
,
True
)
del
self
.
clients
[
'
%s:%d
'
%
addr
]
except
KeyError
:
pass
def
change_username
(
self
,
addr
,
username
):
"""
Update the username of the client.
"""
self
.
clients
[
'
%s:%d
'
%
addr
].
username
=
username
# TODO: notify other clients of changed username
def
send_all
(
self
,
msg
,
sender
=
None
):
"""
Send a message or notification from a client to all connected clients
(optionally including to the sender).
"""
for
c
in
self
.
clients
:
if
self
.
clients
[
c
].
handler
!=
sender
:
self
.
clients
[
c
].
handler
.
send_raw
(
msg
)
class
RequestHandler
(
AsyncBase
,
asyncore
.
dispatcher
):
def
__init__
(
self
,
conn
,
address
,
client
,
server
):
...
...
@@ -86,18 +114,25 @@ class RequestHandler(AsyncBase, asyncore.dispatcher):
self
.
address
=
address
self
.
client
=
client
self
.
server
=
server
self
.
username
=
''
self
.
log
=
self
.
server
.
log
self
.
send_welcome_message
()
def
send_welcome_message
(
self
):
"""
Welcome our new client by sending a welcome message. This message
contains the server version number and a greetings message.
"""
self
.
send_raw
(
"
CHAT/%d.%d/%s
"
\
%
(
MAJOR_VERSION
,
MINOR_VERSION
,
GREETING_MSG
))
def
handle_read
(
self
):
"""
Receive a message from the client. If the connection is somehow broken,
disconnect the client and clean the corresponding data.
"""
buf
=
''
# Receive a message from the client. If the connection is somehow
# broken, disconnect the client and clean the corresponding data.
try
:
while
True
:
chunk
=
self
.
recv
(
1
)
...
...
@@ -115,10 +150,11 @@ class RequestHandler(AsyncBase, asyncore.dispatcher):
# Received a message, so it's time to parse the message.
buf
=
buf
[:
-
1
]
self
.
debug_log
(
'
< %s
'
%
buf
)
self
.
parse_response
(
buf
)
def
handle_error
(
self
):
self
.
server
.
disconnect_client
(
self
.
address
)
def
parse_response
(
self
,
buf
):
"""
>>>
class
DummyServer
(
object
):
...
...
@@ -140,9 +176,24 @@ class RequestHandler(AsyncBase, asyncore.dispatcher):
if
cmd
==
'
USER
'
:
# User changes/sets its username.
if
re
.
match
(
ur
'
^[^\u0000-\u001f\u007f-\u009f/:]+$
'
,
buf
[
5
:]):
if
not
self
.
username
:
self
.
send_all
(
'
JOIN %s
'
%
buf
[
5
:],
True
)
else
:
self
.
send_all
(
'
RENAME %s/%s
'
\
%
(
self
.
username
,
buf
[
5
:]),
True
)
self
.
set_username
(
buf
[
5
:])
return
self
.
send_positive
(
'
Ok
'
)
return
self
.
send_negative
(
'
Invalid username.
'
)
# TODO: user can't send a message if he didn't send his username first.
if
cmd
==
'
SAY
'
:
return
self
.
send_all
(
'
SAY %s/%s
'
%
(
self
.
username
,
buf
[
4
:]))
if
cmd
==
'
NAMES
'
:
self
.
send_raw
(
'
+Ok:
'
)
for
c
in
self
.
server
.
clients
:
self
.
send_raw
(
self
.
server
.
clients
[
c
].
username
)
self
.
send_raw
(
''
)
return
True
return
self
.
send_negative
(
'
Unsupported command.
'
)
def
send_positive
(
self
,
msg
):
...
...
@@ -153,7 +204,12 @@ class RequestHandler(AsyncBase, asyncore.dispatcher):
self
.
send_raw
(
'
-%s
'
%
msg
)
return
False
def
send_all
(
self
,
msg
,
except_sender
=
False
):
self
.
server
.
send_all
(
msg
,
except_sender
and
self
)
return
True
def
set_username
(
self
,
username
):
self
.
username
=
username
self
.
server
.
change_username
(
self
.
address
,
username
)
if
__name__
==
'
__main__
'
:
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment