From a93d17e0e65458e8dbadf5d510229b0a9c9e1470 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Wed, 5 Apr 2017 15:30:10 -0400 Subject: [PATCH 01/16] Two threads of execution example --- concurrentreadandprint.rkt | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 concurrentreadandprint.rkt diff --git a/concurrentreadandprint.rkt b/concurrentreadandprint.rkt new file mode 100644 index 0000000..2272d97 --- /dev/null +++ b/concurrentreadandprint.rkt @@ -0,0 +1,51 @@ +#lang racket +;; author: Ibrahim Mkusa +;; about: print and read concurrently + +;; reads values continously from stdin and redisplays them +(define (read-loop) + (display (read-line)) + (display "\n") + (read-loop) + ) + +(define input-prompt "input: ") +(define output-prompt "output: ") + +;; prompt for username and bind to a variable username +(display "What's your name?\n") +(define username (read-line)) +(define usernamei (string-append username ": ")) ;; make username appear nicer in a prompt +(define fair (make-semaphore 1)) + +;; intelligent read, quits when user types in "quit" +(define (read-loop-i) + (display usernamei) + + (semaphore-wait fair) + (define input (read-line)) + ;; do something over here with input maybe send it out + (cond ((string=? input "quit") (exit))) + (display (string-append output-prompt input "\n")) + (semaphore-post fair) + (read-loop-i) + ) + + +;; print hello world continously +(define (hello-world) + (semaphore-wait fair) + (display "Hello, World!\n") + (semaphore-post fair) + (hello-world)) + +(define t (thread (lambda () + (read-loop-i)))) +(define a (thread (lambda () + (hello-world)))) +;; below doesn't execute +; (sleep 10) +; (kill-thread t) +; (define a (thread (display "hello world!\n"))) +; (display "John: hello soso\n") +; (display "Emmanuel: cumbaya!!!!\n") \ No newline at end of file From 768395102489dab0997ca6b7180c28e51872e665 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Wed, 5 Apr 2017 15:46:50 -0400 Subject: [PATCH 02/16] properly kills threads and returns prompt to main --- concurrentreadandprint.rkt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/concurrentreadandprint.rkt b/concurrentreadandprint.rkt index 2272d97..a9a71ed 100644 --- a/concurrentreadandprint.rkt +++ b/concurrentreadandprint.rkt @@ -2,6 +2,10 @@ ;; author: Ibrahim Mkusa ;; about: print and read concurrently +;; create custodian for managing all resources +;; so we can shutdown everything at once +(define guard (make-custodian (current-custodian))) +(current-custodian guard) ;; reads values continously from stdin and redisplays them (define (read-loop) (display (read-line)) @@ -25,7 +29,8 @@ (semaphore-wait fair) (define input (read-line)) ;; do something over here with input maybe send it out - (cond ((string=? input "quit") (exit))) + (cond ((string=? input "quit") (begin (kill-thread a) + (kill-thread t)))) (display (string-append output-prompt input "\n")) (semaphore-post fair) (read-loop-i) @@ -43,6 +48,8 @@ (read-loop-i)))) (define a (thread (lambda () (hello-world)))) + +(thread-wait t) ;; returns prompt back to drracket ;; below doesn't execute ; (sleep 10) ; (kill-thread t) From 91c611e2afbef6491f16be2fca4bc42fe891b501 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Wed, 5 Apr 2017 16:01:17 -0400 Subject: [PATCH 03/16] fixed an issue with username not appearing nicely --- concurrentreadandprint.rkt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/concurrentreadandprint.rkt b/concurrentreadandprint.rkt index a9a71ed..7e7a78b 100644 --- a/concurrentreadandprint.rkt +++ b/concurrentreadandprint.rkt @@ -1,4 +1,6 @@ #lang racket +(require math/base) ;; for random number generation + ;; author: Ibrahim Mkusa ;; about: print and read concurrently @@ -24,11 +26,15 @@ ;; intelligent read, quits when user types in "quit" (define (read-loop-i) - (display usernamei) + (semaphore-wait fair) + (display usernamei) (define input (read-line)) ;; do something over here with input maybe send it out + + ;; Tests input if its a quit then kills all threads + ;; An if would be better here tbh (cond ((string=? input "quit") (begin (kill-thread a) (kill-thread t)))) (display (string-append output-prompt input "\n")) @@ -38,9 +44,13 @@ ;; print hello world continously +;; "(hello-world)" can be executed as part of background thread +;; that prints in the event there is something in the input port (define (hello-world) + (sleep (random-integer 0 60)) ;; sleep between 0 and 60 seconds to simulate coms + ;; with server (semaphore-wait fair) - (display "Hello, World!\n") + (display "\nHello, World!\n") (semaphore-post fair) (hello-world)) From 819c6a9f7479a743d16b66dbfda31817b1502bd4 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Wed, 5 Apr 2017 16:22:51 -0400 Subject: [PATCH 04/16] Added simulation for multiple users --- concurrentreadandprint.rkt | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/concurrentreadandprint.rkt b/concurrentreadandprint.rkt index 7e7a78b..709dd18 100644 --- a/concurrentreadandprint.rkt +++ b/concurrentreadandprint.rkt @@ -1,8 +1,10 @@ #lang racket (require math/base) ;; for random number generation + ;; author: Ibrahim Mkusa ;; about: print and read concurrently +;; notes: output may need to be aligned and formatted nicely ;; create custodian for managing all resources ;; so we can shutdown everything at once @@ -28,7 +30,7 @@ (define (read-loop-i) - (semaphore-wait fair) + ;(semaphore-wait fair) (display usernamei) (define input (read-line)) ;; do something over here with input maybe send it out @@ -38,7 +40,7 @@ (cond ((string=? input "quit") (begin (kill-thread a) (kill-thread t)))) (display (string-append output-prompt input "\n")) - (semaphore-post fair) + ;(semaphore-post fair) (read-loop-i) ) @@ -47,11 +49,16 @@ ;; "(hello-world)" can be executed as part of background thread ;; that prints in the event there is something in the input port (define (hello-world) - (sleep (random-integer 0 60)) ;; sleep between 0 and 60 seconds to simulate coms + (sleep (random-integer 0 15)) ;; sleep between 0 and 15 seconds to simulate coms ;; with server - (semaphore-wait fair) - (display "\nHello, World!\n") - (semaphore-post fair) + ;(semaphore-wait fair) + ;; we will retrieve the line printed below from the server + ;; at this time we simulate the input from different users + (define what-to-print (random-integer 0 2)) + (if (= what-to-print 0) + (display "Doug: What's up, up?\n") + (display "Fred: Looking good, good!\n")) + ;(semaphore-post fair) (hello-world)) (define t (thread (lambda () From 56bc37f69d92a37cea8b6f0e3ca1ebbf970397a1 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Wed, 5 Apr 2017 16:39:47 -0400 Subject: [PATCH 05/16] I can read and process input iteratively --- concurrentreadandprint.rkt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/concurrentreadandprint.rkt b/concurrentreadandprint.rkt index 709dd18..84882b4 100644 --- a/concurrentreadandprint.rkt +++ b/concurrentreadandprint.rkt @@ -5,11 +5,13 @@ ;; author: Ibrahim Mkusa ;; about: print and read concurrently ;; notes: output may need to be aligned and formatted nicely +;; look into +;; https://docs.racket-lang.org/gui/text-field_.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._text-field~25%29._get-editor%29%29 ;; create custodian for managing all resources ;; so we can shutdown everything at once -(define guard (make-custodian (current-custodian))) -(current-custodian guard) +;(define guard (make-custodian (current-custodian))) +;(current-custodian guard) ;; reads values continously from stdin and redisplays them (define (read-loop) (display (read-line)) From c426214e24893a895aa794f02b2e8728410c0033 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Wed, 5 Apr 2017 16:51:51 -0400 Subject: [PATCH 06/16] Lets try communication over tcp on localhost crpovertcp.rkt --- crpovertcp.rkt | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 crpovertcp.rkt diff --git a/crpovertcp.rkt b/crpovertcp.rkt new file mode 100644 index 0000000..84882b4 --- /dev/null +++ b/crpovertcp.rkt @@ -0,0 +1,77 @@ +#lang racket +(require math/base) ;; for random number generation + + +;; author: Ibrahim Mkusa +;; about: print and read concurrently +;; notes: output may need to be aligned and formatted nicely +;; look into +;; https://docs.racket-lang.org/gui/text-field_.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._text-field~25%29._get-editor%29%29 + +;; create custodian for managing all resources +;; so we can shutdown everything at once +;(define guard (make-custodian (current-custodian))) +;(current-custodian guard) +;; reads values continously from stdin and redisplays them +(define (read-loop) + (display (read-line)) + (display "\n") + (read-loop) + ) + +(define input-prompt "input: ") +(define output-prompt "output: ") + +;; prompt for username and bind to a variable username +(display "What's your name?\n") +(define username (read-line)) +(define usernamei (string-append username ": ")) ;; make username appear nicer in a prompt +(define fair (make-semaphore 1)) + +;; intelligent read, quits when user types in "quit" +(define (read-loop-i) + + + ;(semaphore-wait fair) + (display usernamei) + (define input (read-line)) + ;; do something over here with input maybe send it out + + ;; Tests input if its a quit then kills all threads + ;; An if would be better here tbh + (cond ((string=? input "quit") (begin (kill-thread a) + (kill-thread t)))) + (display (string-append output-prompt input "\n")) + ;(semaphore-post fair) + (read-loop-i) + ) + + +;; print hello world continously +;; "(hello-world)" can be executed as part of background thread +;; that prints in the event there is something in the input port +(define (hello-world) + (sleep (random-integer 0 15)) ;; sleep between 0 and 15 seconds to simulate coms + ;; with server + ;(semaphore-wait fair) + ;; we will retrieve the line printed below from the server + ;; at this time we simulate the input from different users + (define what-to-print (random-integer 0 2)) + (if (= what-to-print 0) + (display "Doug: What's up, up?\n") + (display "Fred: Looking good, good!\n")) + ;(semaphore-post fair) + (hello-world)) + +(define t (thread (lambda () + (read-loop-i)))) +(define a (thread (lambda () + (hello-world)))) + +(thread-wait t) ;; returns prompt back to drracket +;; below doesn't execute +; (sleep 10) +; (kill-thread t) +; (define a (thread (display "hello world!\n"))) +; (display "John: hello soso\n") +; (display "Emmanuel: cumbaya!!!!\n") \ No newline at end of file From 1edfa0442c29f5d69e720763ae22b330de2a4388 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Fri, 7 Apr 2017 13:18:20 -0400 Subject: [PATCH 07/16] iterative updates --- Makefile | 3 +++ crpovertcp.rkt | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..eda5bbb --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ +# Remove idiotic save files +clean: + rm -rf *~ diff --git a/crpovertcp.rkt b/crpovertcp.rkt index 84882b4..7ec3745 100644 --- a/crpovertcp.rkt +++ b/crpovertcp.rkt @@ -1,6 +1,60 @@ #lang racket (require math/base) ;; for random number generation +;; globals +;; must control access via semaphore as listener thread or broadcast thread +;; might need to access it +(define connections '()) + +;; This is a single server communicating directly to the client + +;;;;;;;;;;;;;;;;;;;;;;Server Client communication;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define (serve in-port out-port) + (let loop [] + (define evt (sync/timeout 2 + (read-line-evt in-port 'any) + (thread-receive-evt))) + (cond + [(not evt) + (displayln "Timed out, exiting") + (tcp-abandon-port in-port) + (tcp-abandon-port out-port)] + [(string? evt) + (fprintf out-port "~a~n" evt) ;; echoes back received string + (flush-output out-port) ;; flushes the buffer + (loop)] ;; iterates again + [else + (printf "Received a message in mailbox: ~a~n" + (thread-receive)) + (loop)]))) + +(define port-num 4322) +(define (start-server) + (define listener (tcp-listen port-num)) + (thread + (lambda () + (let loop () ;; the server now loops continously listening in for connections + (define-values [in-port out-port] (tcp-accept listener)) + ;; lets add this open ports to global list of connections + (semaphore-wait fair) + (append connections (list (list in-port out-port))) + (semaphore-post fair) + (serve in-port out-port) ; could be do the greeting in here + (loop))))) + +(start-server) + +(define client-thread + (thread + (lambda () + (define-values [in-port out-port] (tcp-connect "localhost" port-num)) + + (display "first\nsecond\nthird\n" out-port) + (flush-output out-port) + ; copy-port will block until EOF is read from in-port + (copy-port in-port (current-output-port))))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; author: Ibrahim Mkusa ;; about: print and read concurrently From e0354fd1c24c2a918d433837b727016474c19c0b Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Sun, 9 Apr 2017 12:53:03 -0400 Subject: [PATCH 08/16] keeping count of input and output ports directly is feasible. Trying a different way. --- crpovertcp.rkt | 98 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/crpovertcp.rkt b/crpovertcp.rkt index 7ec3745..de04790 100644 --- a/crpovertcp.rkt +++ b/crpovertcp.rkt @@ -4,8 +4,101 @@ ;; globals ;; must control access via semaphore as listener thread or broadcast thread ;; might need to access it -(define connections '()) +(define connections '()) ;; maintains a list of open ports +;; ((in1, out1), (in2, out2), (in3, out3), (in4, out4) ...) +;; lets keep thread descriptor values +; + +(define fair (make-semaphore 1)) ;; managing connections above + +(define can-i-broadcast (make-semaphore 1)) + +;; alternative one keep running list of input and output ports directly +;; broadcasts a message to all connected clients +(define broadcast-message + (lambda (message connections) + (map send_message connections) + 'ok)) + +; port pair -> '(input-port output-port) + +(define (get-input-port port-pair) + (car port-pair)) + +(define (get-output-port port-pair) + (cadr port-pair)) + +;; gets pair of input and output port of a client and sends a message +(define send-message + (lambda (client_ports) + (displayln message (get-output-port (client-ports))) + (flush-output (get-output-port (client-ports))) + 'ok)) + + +;; + +;; This is a relay server making two clients communicate +;; Both `server' and `accept-and-handle' change +;; to use a custodian. +;; To start server +;; (define stop (serve 8080)) +;; (stop) to close the server + +(define (serve port-no) + (define main-cust (make-custodian)) + (parameterize ([current-custodian main-cust]) + (define listener (tcp-listen port-no 5 #t)) + (define (loop) + (accept-and-handle listener) + (loop)) + (thread loop)) + (lambda () + (displayln "\nGoodbye, shutting down all services\n") + (custodian-shutdown-all main-cust))) + +(define (accept-and-handle listener) + (define cust (make-custodian)) + (parameterize ([current-custodian cust]) + (define-values (in out) (tcp-accept listener)) + (semaphore-wait fair) + ;; keep track of open ports + (append connections (list (list in out))) + (semaphore-wait fiar) + + ; thread will communicate to all clients at once in a broadcast + ; manner + (thread (lambda () + (handle in out) ;; this handles connection with that specific client + (close-input-port in) + (close-output-port out))) + ) + ;; Watcher thread: + ;; kills current thread for waiting too long for connection from + ;; clients + (thread (lambda () + (sleep 120) + (custodian-shutdown-all cust)))) + +; (define (handle connections) +; ()) +;; each thread needs 2 new threads +(define (handle in out) + ; define function to deal with in + (define (something-to-say in) + (sync/timeout 4 (read-line-evt in 'linefeed))) + ; define function to deal with out + ; thread them each + ; (server-loop in out) + (sleep 5) ;; wait 5 seconds to guarantee client has already send message + (define echo (read-line in)) ;; bind message to echo + (displayln (string-append echo "\n")) + ; echo back the message, appending echo + ; could regex match the input to extract the name + (writeln "Admin: Hello there" out) ;; append "echo " to echo and send back + (flush-output out) +) ;; This is a single server communicating directly to the client ;;;;;;;;;;;;;;;;;;;;;;Server Client communication;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -80,7 +173,6 @@ (display "What's your name?\n") (define username (read-line)) (define usernamei (string-append username ": ")) ;; make username appear nicer in a prompt -(define fair (make-semaphore 1)) ;; intelligent read, quits when user types in "quit" (define (read-loop-i) @@ -128,4 +220,4 @@ ; (kill-thread t) ; (define a (thread (display "hello world!\n"))) ; (display "John: hello soso\n") -; (display "Emmanuel: cumbaya!!!!\n") \ No newline at end of file +; (display "Emmanuel: cumbaya!!!!\n") From 53bc7d0232eb8e8923d6721fcfd1d37925439c6e Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Sun, 9 Apr 2017 12:59:00 -0400 Subject: [PATCH 09/16] cleaned up crpovertcp.rkt --- crpovertcp.rkt | 68 -------------------------------------------------- 1 file changed, 68 deletions(-) diff --git a/crpovertcp.rkt b/crpovertcp.rkt index de04790..57874a8 100644 --- a/crpovertcp.rkt +++ b/crpovertcp.rkt @@ -14,28 +14,6 @@ (define can-i-broadcast (make-semaphore 1)) -;; alternative one keep running list of input and output ports directly -;; broadcasts a message to all connected clients -(define broadcast-message - (lambda (message connections) - (map send_message connections) - 'ok)) - -; port pair -> '(input-port output-port) - -(define (get-input-port port-pair) - (car port-pair)) - -(define (get-output-port port-pair) - (cadr port-pair)) - -;; gets pair of input and output port of a client and sends a message -(define send-message - (lambda (client_ports) - (displayln message (get-output-port (client-ports))) - (flush-output (get-output-port (client-ports))) - 'ok)) - ;; @@ -100,52 +78,6 @@ (flush-output out) ) ;; This is a single server communicating directly to the client - -;;;;;;;;;;;;;;;;;;;;;;Server Client communication;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define (serve in-port out-port) - (let loop [] - (define evt (sync/timeout 2 - (read-line-evt in-port 'any) - (thread-receive-evt))) - (cond - [(not evt) - (displayln "Timed out, exiting") - (tcp-abandon-port in-port) - (tcp-abandon-port out-port)] - [(string? evt) - (fprintf out-port "~a~n" evt) ;; echoes back received string - (flush-output out-port) ;; flushes the buffer - (loop)] ;; iterates again - [else - (printf "Received a message in mailbox: ~a~n" - (thread-receive)) - (loop)]))) - -(define port-num 4322) -(define (start-server) - (define listener (tcp-listen port-num)) - (thread - (lambda () - (let loop () ;; the server now loops continously listening in for connections - (define-values [in-port out-port] (tcp-accept listener)) - ;; lets add this open ports to global list of connections - (semaphore-wait fair) - (append connections (list (list in-port out-port))) - (semaphore-post fair) - (serve in-port out-port) ; could be do the greeting in here - (loop))))) - -(start-server) - -(define client-thread - (thread - (lambda () - (define-values [in-port out-port] (tcp-connect "localhost" port-num)) - - (display "first\nsecond\nthird\n" out-port) - (flush-output out-port) - ; copy-port will block until EOF is read from in-port - (copy-port in-port (current-output-port))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From 2e0ddaaf3a67659ea5448ea54bd563325d007021 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Sun, 9 Apr 2017 13:02:30 -0400 Subject: [PATCH 10/16] partitioning crpovertcp.rkt to dedicated server.rkt and client.rkt files --- client.rkt | 77 ++++++++++++++++++++++++++ server.rkt | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 client.rkt create mode 100644 server.rkt diff --git a/client.rkt b/client.rkt new file mode 100644 index 0000000..70df4e6 --- /dev/null +++ b/client.rkt @@ -0,0 +1,77 @@ +#lang racket +(require math/base) ;; for random number generation + +;; author: Ibrahim Mkusa +;; about: print and read concurrently +;; notes: output may need to be aligned and formatted nicely +;; look into +;; https://docs.racket-lang.org/gui/text-field_.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._text-field~25%29._get-editor%29%29 + +;; create custodian for managing all resources +;; so we can shutdown everything at once +;(define guard (make-custodian (current-custodian))) +;(current-custodian guard) +;; reads values continously from stdin and redisplays them +(define (read-loop) + (display (read-line)) + (display "\n") + (read-loop) + ) + +(define input-prompt "input: ") +(define output-prompt "output: ") + +(define fair (make-semaphore 1)) + +;; prompt for username and bind to a variable username +(display "What's your name?\n") +(define username (read-line)) +(define usernamei (string-append username ": ")) ;; make username appear nicer in a prompt + +;; intelligent read, quits when user types in "quit" +(define (read-loop-i) + + + ;(semaphore-wait fair) + (display usernamei) + (define input (read-line)) + ;; do something over here with input maybe send it out + + ;; Tests input if its a quit then kills all threads + ;; An if would be better here tbh + (cond ((string=? input "quit") (begin (kill-thread a) + (kill-thread t)))) + (display (string-append output-prompt input "\n")) + ;(semaphore-post fair) + (read-loop-i) + ) + + +;; print hello world continously +;; "(hello-world)" can be executed as part of background thread +;; that prints in the event there is something in the input port +(define (hello-world) + (sleep (random-integer 0 15)) ;; sleep between 0 and 15 seconds to simulate coms + ;; with server + ;(semaphore-wait fair) + ;; we will retrieve the line printed below from the server + ;; at this time we simulate the input from different users + (define what-to-print (random-integer 0 2)) + (if (= what-to-print 0) + (display "Doug: What's up, up?\n") + (display "Fred: Looking good, good!\n")) + ;(semaphore-post fair) + (hello-world)) + +(define t (thread (lambda () + (read-loop-i)))) +(define a (thread (lambda () + (hello-world)))) + +(thread-wait t) ;; returns prompt back to drracket +;; below doesn't execute +; (sleep 10) +; (kill-thread t) +; (define a (thread (display "hello world!\n"))) +; (display "John: hello soso\n") +; (display "Emmanuel: cumbaya!!!!\n") diff --git a/server.rkt b/server.rkt new file mode 100644 index 0000000..57874a8 --- /dev/null +++ b/server.rkt @@ -0,0 +1,155 @@ +#lang racket +(require math/base) ;; for random number generation + +;; globals +;; must control access via semaphore as listener thread or broadcast thread +;; might need to access it +(define connections '()) ;; maintains a list of open ports +;; ((in1, out1), (in2, out2), (in3, out3), (in4, out4) ...) + +;; lets keep thread descriptor values +; + +(define fair (make-semaphore 1)) ;; managing connections above + +(define can-i-broadcast (make-semaphore 1)) + + +;; + +;; This is a relay server making two clients communicate +;; Both `server' and `accept-and-handle' change +;; to use a custodian. +;; To start server +;; (define stop (serve 8080)) +;; (stop) to close the server + +(define (serve port-no) + (define main-cust (make-custodian)) + (parameterize ([current-custodian main-cust]) + (define listener (tcp-listen port-no 5 #t)) + (define (loop) + (accept-and-handle listener) + (loop)) + (thread loop)) + (lambda () + (displayln "\nGoodbye, shutting down all services\n") + (custodian-shutdown-all main-cust))) + +(define (accept-and-handle listener) + (define cust (make-custodian)) + (parameterize ([current-custodian cust]) + (define-values (in out) (tcp-accept listener)) + (semaphore-wait fair) + ;; keep track of open ports + (append connections (list (list in out))) + (semaphore-wait fiar) + + ; thread will communicate to all clients at once in a broadcast + ; manner + (thread (lambda () + (handle in out) ;; this handles connection with that specific client + (close-input-port in) + (close-output-port out))) + ) + ;; Watcher thread: + ;; kills current thread for waiting too long for connection from + ;; clients + (thread (lambda () + (sleep 120) + (custodian-shutdown-all cust)))) + +; (define (handle connections) +; ()) +;; each thread needs 2 new threads +(define (handle in out) + ; define function to deal with in + (define (something-to-say in) + (sync/timeout 4 (read-line-evt in 'linefeed))) + ; define function to deal with out + ; thread them each + ; (server-loop in out) + (sleep 5) ;; wait 5 seconds to guarantee client has already send message + (define echo (read-line in)) ;; bind message to echo + (displayln (string-append echo "\n")) + ; echo back the message, appending echo + ; could regex match the input to extract the name + (writeln "Admin: Hello there" out) ;; append "echo " to echo and send back + (flush-output out) +) +;; This is a single server communicating directly to the client +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;; author: Ibrahim Mkusa +;; about: print and read concurrently +;; notes: output may need to be aligned and formatted nicely +;; look into +;; https://docs.racket-lang.org/gui/text-field_.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._text-field~25%29._get-editor%29%29 + +;; create custodian for managing all resources +;; so we can shutdown everything at once +;(define guard (make-custodian (current-custodian))) +;(current-custodian guard) +;; reads values continously from stdin and redisplays them +(define (read-loop) + (display (read-line)) + (display "\n") + (read-loop) + ) + +(define input-prompt "input: ") +(define output-prompt "output: ") + +;; prompt for username and bind to a variable username +(display "What's your name?\n") +(define username (read-line)) +(define usernamei (string-append username ": ")) ;; make username appear nicer in a prompt + +;; intelligent read, quits when user types in "quit" +(define (read-loop-i) + + + ;(semaphore-wait fair) + (display usernamei) + (define input (read-line)) + ;; do something over here with input maybe send it out + + ;; Tests input if its a quit then kills all threads + ;; An if would be better here tbh + (cond ((string=? input "quit") (begin (kill-thread a) + (kill-thread t)))) + (display (string-append output-prompt input "\n")) + ;(semaphore-post fair) + (read-loop-i) + ) + + +;; print hello world continously +;; "(hello-world)" can be executed as part of background thread +;; that prints in the event there is something in the input port +(define (hello-world) + (sleep (random-integer 0 15)) ;; sleep between 0 and 15 seconds to simulate coms + ;; with server + ;(semaphore-wait fair) + ;; we will retrieve the line printed below from the server + ;; at this time we simulate the input from different users + (define what-to-print (random-integer 0 2)) + (if (= what-to-print 0) + (display "Doug: What's up, up?\n") + (display "Fred: Looking good, good!\n")) + ;(semaphore-post fair) + (hello-world)) + +(define t (thread (lambda () + (read-loop-i)))) +(define a (thread (lambda () + (hello-world)))) + +(thread-wait t) ;; returns prompt back to drracket +;; below doesn't execute +; (sleep 10) +; (kill-thread t) +; (define a (thread (display "hello world!\n"))) +; (display "John: hello soso\n") +; (display "Emmanuel: cumbaya!!!!\n") From f56f1cc46d738bc76820977af8c6a372f9702df4 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Sun, 9 Apr 2017 14:56:46 -0400 Subject: [PATCH 11/16] server code for interacting with client is done, not tested. Working on server broadcast function --- server.rkt | 150 +++++++++++++++++++---------------------------------- 1 file changed, 54 insertions(+), 96 deletions(-) diff --git a/server.rkt b/server.rkt index 57874a8..c5bb6f3 100644 --- a/server.rkt +++ b/server.rkt @@ -6,11 +6,24 @@ ;; might need to access it (define connections '()) ;; maintains a list of open ports ;; ((in1, out1), (in2, out2), (in3, out3), (in4, out4) ...) +(define connections-s (make-semaphore 1)) ;; control access to connections +;; every 5 seconds run to broadcast top message in list +;; and remove it from list +(define messages-s (make-semaphore 1)) ;; control access to messages +(define messages '()) ;; stores a list of messages(strings) from currents + +(define threads-s (make-semaphore 1)) ;; control access to threads ;; lets keep thread descriptor values -; +(define threads '()) ;; stores a list of client serving threads as thread descriptor values -(define fair (make-semaphore 1)) ;; managing connections above +;; define a broadcast function +(define broadcast + (lambda () + (semaphore-wait messages-s) + (semaphore-wait threads-s) + (map (lambda (thread-descriptor) + ())))) (define can-i-broadcast (make-semaphore 1)) @@ -40,116 +53,61 @@ (define cust (make-custodian)) (parameterize ([current-custodian cust]) (define-values (in out) (tcp-accept listener)) - (semaphore-wait fair) + (semaphore-wait connections-s) ;; keep track of open ports (append connections (list (list in out))) - (semaphore-wait fiar) + (semaphore-wait connections-s) - ; thread will communicate to all clients at once in a broadcast - ; manner - (thread (lambda () + ; start a thread to deal with specific client and add descriptor value to the list of threads + (append threads (list (thread (lambda () (handle in out) ;; this handles connection with that specific client (close-input-port in) - (close-output-port out))) - ) + (close-output-port out)))) + ) ;; Watcher thread: ;; kills current thread for waiting too long for connection from ;; clients (thread (lambda () (sleep 120) - (custodian-shutdown-all cust)))) + (custodian-shutdown-all cust))))) ; (define (handle connections) ; ()) ;; each thread needs 2 new threads (define (handle in out) - ; define function to deal with in + ; define function to deal with incoming messages from client (define (something-to-say in) - (sync/timeout 4 (read-line-evt in 'linefeed))) + (define evt-t0 (sync/timeout 120 (read-line-evt in 'linefeed))) + (cond [(not evt-t0) + (displayln "Nothing received from " (current-thread) "exiting")] + [(string? evt-t0) + (semaphore-wait messages-s) + ; append the message to list of messages + (append messages (list evt-t0)) + (semaphore-post messages-s)])) + + ; define function to deal with out + (define (something-to-send out) + (define evt-t1 (sync/timeout 120 (thread-receive-evt))) + ;; send message to client + (fprintf out "~a~n" (thread-receive)) + (flush-output out) + ) ; thread them each + + ;; i could bind to values, and call wait on them + ;; thread that deals with incoming messages for that particular thread + (thread (lambda () + (let loop [] + (something-to-say in) + (loop)))) + + (thread (lambda () + (let loop [] + (something-to-say out) + (loop)))) ; (server-loop in out) - (sleep 5) ;; wait 5 seconds to guarantee client has already send message - (define echo (read-line in)) ;; bind message to echo - (displayln (string-append echo "\n")) - ; echo back the message, appending echo - ; could regex match the input to extract the name - (writeln "Admin: Hello there" out) ;; append "echo " to echo and send back - (flush-output out) -) -;; This is a single server communicating directly to the client -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -;; author: Ibrahim Mkusa -;; about: print and read concurrently -;; notes: output may need to be aligned and formatted nicely -;; look into -;; https://docs.racket-lang.org/gui/text-field_.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._text-field~25%29._get-editor%29%29 - -;; create custodian for managing all resources -;; so we can shutdown everything at once -;(define guard (make-custodian (current-custodian))) -;(current-custodian guard) -;; reads values continously from stdin and redisplays them -(define (read-loop) - (display (read-line)) - (display "\n") - (read-loop) - ) - -(define input-prompt "input: ") -(define output-prompt "output: ") - -;; prompt for username and bind to a variable username -(display "What's your name?\n") -(define username (read-line)) -(define usernamei (string-append username ": ")) ;; make username appear nicer in a prompt - -;; intelligent read, quits when user types in "quit" -(define (read-loop-i) - - - ;(semaphore-wait fair) - (display usernamei) - (define input (read-line)) - ;; do something over here with input maybe send it out - - ;; Tests input if its a quit then kills all threads - ;; An if would be better here tbh - (cond ((string=? input "quit") (begin (kill-thread a) - (kill-thread t)))) - (display (string-append output-prompt input "\n")) - ;(semaphore-post fair) - (read-loop-i) - ) - - -;; print hello world continously -;; "(hello-world)" can be executed as part of background thread -;; that prints in the event there is something in the input port -(define (hello-world) - (sleep (random-integer 0 15)) ;; sleep between 0 and 15 seconds to simulate coms - ;; with server - ;(semaphore-wait fair) - ;; we will retrieve the line printed below from the server - ;; at this time we simulate the input from different users - (define what-to-print (random-integer 0 2)) - (if (= what-to-print 0) - (display "Doug: What's up, up?\n") - (display "Fred: Looking good, good!\n")) - ;(semaphore-post fair) - (hello-world)) - -(define t (thread (lambda () - (read-loop-i)))) -(define a (thread (lambda () - (hello-world)))) - -(thread-wait t) ;; returns prompt back to drracket -;; below doesn't execute -; (sleep 10) -; (kill-thread t) -; (define a (thread (display "hello world!\n"))) -; (display "John: hello soso\n") -; (display "Emmanuel: cumbaya!!!!\n") + ; (sleep 5) ;; wait 5 seconds to guarantee client has already send message + 'ok + ) From ba3f6821f5ef38b6e2e1990581765f80203817c9 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Sun, 9 Apr 2017 15:19:57 -0400 Subject: [PATCH 12/16] server.rkt is done, with exception of testing. Moving on to client.rkt --- client.rkt | 2 ++ server.rkt | 22 ++++++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/client.rkt b/client.rkt index 70df4e6..f0d3578 100644 --- a/client.rkt +++ b/client.rkt @@ -12,6 +12,8 @@ ;(define guard (make-custodian (current-custodian))) ;(current-custodian guard) ;; reads values continously from stdin and redisplays them + +;;;;;; NOT IN USE ;;;;;;; (define (read-loop) (display (read-line)) (display "\n") diff --git a/server.rkt b/server.rkt index c5bb6f3..5322a3d 100644 --- a/server.rkt +++ b/server.rkt @@ -22,11 +22,15 @@ (lambda () (semaphore-wait messages-s) (semaphore-wait threads-s) - (map (lambda (thread-descriptor) - ())))) - -(define can-i-broadcast (make-semaphore 1)) - + (if (not (null? messages)) + (begin (map (lambda (thread-descriptor) + (thread-send thread-descriptor (first messages)))) + (set! messages (rest messages)) + ) + (display "No message to display\n") ; for later create file port for errors and save error messages to that file + ) + (semaphore-post threads-s) + (semaphore-post messages-s))) ;; @@ -44,7 +48,13 @@ (define (loop) (accept-and-handle listener) (loop)) - (thread loop)) + (thread loop) + ;; Create a thread whose job is to simply call broadcast iteratively + (thread (lambda () + (let loopb [] + broadcast + (sleep 10) ;; sleep for 10 seconds between broadcasts + (loopb))))) (lambda () (displayln "\nGoodbye, shutting down all services\n") (custodian-shutdown-all main-cust))) From f0d361b49c80d9fb78c67f006ad49b1062e8ed64 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Sun, 9 Apr 2017 20:50:20 -0400 Subject: [PATCH 13/16] updates to server.rkt and client.rkt --- client.rkt | 107 ++++++++++++++++++++++--------------- concurrentreadandprint.rkt | 2 +- server.rkt | 69 +++++++++++++++--------- 3 files changed, 109 insertions(+), 69 deletions(-) diff --git a/client.rkt b/client.rkt index f0d3578..25be149 100644 --- a/client.rkt +++ b/client.rkt @@ -13,67 +13,90 @@ ;(current-custodian guard) ;; reads values continously from stdin and redisplays them -;;;;;; NOT IN USE ;;;;;;; -(define (read-loop) - (display (read-line)) - (display "\n") - (read-loop) - ) +;; Notes connect to server on localhost +;; use client template of tcpvanilla +;; use event for read-write -(define input-prompt "input: ") -(define output-prompt "output: ") +;; modify read-loop-i +; read a value and send it to server via output-port -(define fair (make-semaphore 1)) +; is there something in the input port. If yes? display it +; in the hello world -;; prompt for username and bind to a variable username -(display "What's your name?\n") -(define username (read-line)) -(define usernamei (string-append username ": ")) ;; make username appear nicer in a prompt +; make connection to server +(define (client port-no) + (define main-client-cust (make-custodian)) + (parameterize ([current-custodian main-client-cust]) + ;; connect to server at port 8080 + (define-values (in out) (tcp-connect "localhost" port-no)) ;; define values + (display in) + (displayln out) + ;; binds to multiple values akin to unpacking tuples in python + (display "What's your name?\n") + (define username (read-line)) -;; intelligent read, quits when user types in "quit" -(define (read-loop-i) - - + ; (thread (lambda () + ;; make threads 2 lines + (define a (thread + (lambda () + (let loop [] + (receive-messages in) + (sleep 1) + (loop))))) + (define t (thread + (lambda () + (let loop [] + (send-messages username out) + (sleep 1) + (loop))))) + (thread-wait t) ;; returns prompt back to drracket + (close-input-port in) + (close-output-port out)) + (custodian-shutdown-all main-client-cust)) + + +;; the send-messages +(define (send-messages username out) + ;; intelligent read, quits when user types in "quit" ;(semaphore-wait fair) - (display usernamei) + ; (display usernamei) (define input (read-line)) ;; do something over here with input maybe send it out ;; Tests input if its a quit then kills all threads ;; An if would be better here tbh - (cond ((string=? input "quit") (begin (kill-thread a) - (kill-thread t)))) - (display (string-append output-prompt input "\n")) + ;; (cond ((string=? input "quit") (begin (kill-thread a) + ;(kill-thread t)))) + (cond ((string=? input "quit") (exit))) + ;; modify to send messages to out port + (displayln (string-append username ": " input) out) + (flush-output out) + ;(semaphore-post fair) - (read-loop-i) - ) + ; (read-loop-i out) +) + ;; print hello world continously ;; "(hello-world)" can be executed as part of background thread ;; that prints in the event there is something in the input port -(define (hello-world) - (sleep (random-integer 0 15)) ;; sleep between 0 and 15 seconds to simulate coms +(define (receive-messages in) + ; (sleep (random-integer 0 15)) ;; sleep between 0 and 15 seconds to simulate coms ;; with server ;(semaphore-wait fair) ;; we will retrieve the line printed below from the server - ;; at this time we simulate the input from different users - (define what-to-print (random-integer 0 2)) - (if (= what-to-print 0) - (display "Doug: What's up, up?\n") - (display "Fred: Looking good, good!\n")) + (define evt (sync/timeout 30 (read-line-evt in))) + (cond [(eof-object? evt) + (displayln "Server connection closed") + (exit)] + [(string? evt) + (displayln evt)] ; could time stamp here or to send message + [else + (displayln (string-append "Nothing received from server for 2 minutes."))] + ) ;(semaphore-post fair) - (hello-world)) +) -(define t (thread (lambda () - (read-loop-i)))) -(define a (thread (lambda () - (hello-world)))) +(define stop (client 4321)) -(thread-wait t) ;; returns prompt back to drracket -;; below doesn't execute -; (sleep 10) -; (kill-thread t) -; (define a (thread (display "hello world!\n"))) -; (display "John: hello soso\n") -; (display "Emmanuel: cumbaya!!!!\n") diff --git a/concurrentreadandprint.rkt b/concurrentreadandprint.rkt index 84882b4..f67f1dd 100644 --- a/concurrentreadandprint.rkt +++ b/concurrentreadandprint.rkt @@ -74,4 +74,4 @@ ; (kill-thread t) ; (define a (thread (display "hello world!\n"))) ; (display "John: hello soso\n") -; (display "Emmanuel: cumbaya!!!!\n") \ No newline at end of file +; (display "Emmanuel: cumbaya!!!!\n") diff --git a/server.rkt b/server.rkt index 5322a3d..d1f5a98 100644 --- a/server.rkt +++ b/server.rkt @@ -11,26 +11,13 @@ ;; every 5 seconds run to broadcast top message in list ;; and remove it from list (define messages-s (make-semaphore 1)) ;; control access to messages -(define messages '()) ;; stores a list of messages(strings) from currents +(define messages '("hello, world!")) ;; stores a list of messages(strings) from currents (define threads-s (make-semaphore 1)) ;; control access to threads ;; lets keep thread descriptor values (define threads '()) ;; stores a list of client serving threads as thread descriptor values -;; define a broadcast function -(define broadcast - (lambda () - (semaphore-wait messages-s) - (semaphore-wait threads-s) - (if (not (null? messages)) - (begin (map (lambda (thread-descriptor) - (thread-send thread-descriptor (first messages)))) - (set! messages (rest messages)) - ) - (display "No message to display\n") ; for later create file port for errors and save error messages to that file - ) - (semaphore-post threads-s) - (semaphore-post messages-s))) + ;; @@ -52,7 +39,8 @@ ;; Create a thread whose job is to simply call broadcast iteratively (thread (lambda () (let loopb [] - broadcast + (sleep 30) ;; wait 30 secs before beginning to broadcast + (broadcast) (sleep 10) ;; sleep for 10 seconds between broadcasts (loopb))))) (lambda () @@ -63,22 +51,26 @@ (define cust (make-custodian)) (parameterize ([current-custodian cust]) (define-values (in out) (tcp-accept listener)) + ; discard request header + ; Discard the request header (up to blank line): + (regexp-match #rx"(\r\n|^)\r\n" in) (semaphore-wait connections-s) ;; keep track of open ports - (append connections (list (list in out))) - (semaphore-wait connections-s) + (set! connections (append connections (list (list in out)))) + (semaphore-post connections-s) ; start a thread to deal with specific client and add descriptor value to the list of threads - (append threads (list (thread (lambda () + (set! threads (append threads (list (thread (lambda () (handle in out) ;; this handles connection with that specific client (close-input-port in) (close-output-port out)))) ) + ) ;; Watcher thread: ;; kills current thread for waiting too long for connection from ;; clients (thread (lambda () - (sleep 120) + (sleep 360) (custodian-shutdown-all cust))))) ; (define (handle connections) @@ -87,14 +79,19 @@ (define (handle in out) ; define function to deal with incoming messages from client (define (something-to-say in) - (define evt-t0 (sync/timeout 120 (read-line-evt in 'linefeed))) - (cond [(not evt-t0) - (displayln "Nothing received from " (current-thread) "exiting")] + (define evt-t0 (sync/timeout 30 (read-line-evt in 'linefeed))) + (cond [(eof-object? evt-t0) + (displayln (string-append "Connection closed " (current-thread) "exiting")) + (exit) + ] [(string? evt-t0) (semaphore-wait messages-s) ; append the message to list of messages - (append messages (list evt-t0)) - (semaphore-post messages-s)])) + (display (string-append evt-t0 "\n")) + (set! messages (append messages (list evt-t0))) + (semaphore-post messages-s)] + [else + (displayln (string-append "Nothing received from " (current-thread)))])) ; define function to deal with out @@ -111,13 +108,33 @@ (thread (lambda () (let loop [] (something-to-say in) + (sleep 1) (loop)))) (thread (lambda () (let loop [] - (something-to-say out) + (something-to-send out) + (sleep 1) (loop)))) ; (server-loop in out) ; (sleep 5) ;; wait 5 seconds to guarantee client has already send message 'ok ) + +;; define a broadcast function +(define broadcast + (lambda () + (semaphore-wait messages-s) + (semaphore-wait threads-s) + (if (not (null? messages)) + (begin (map (lambda (thread-descriptor) + (thread-send thread-descriptor (first messages))) + threads) + (set! messages (rest messages)) + ) + (display "No message to display\n") ; for later create file port for errors and save error messages to that file + ) + (semaphore-post threads-s) + (semaphore-post messages-s))) + +(define stop (serve 4321)) ;; start server then close with stop \ No newline at end of file From 404f3d7edfe648dc3fd51c1afc1b3984557f1902 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Sun, 9 Apr 2017 22:29:59 -0400 Subject: [PATCH 14/16] Added tcpcommunication.rkt --- tcpcommunication.rkt | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tcpcommunication.rkt diff --git a/tcpcommunication.rkt b/tcpcommunication.rkt new file mode 100644 index 0000000..27a5151 --- /dev/null +++ b/tcpcommunication.rkt @@ -0,0 +1,57 @@ +#lang racket +(require math/base) ;; for random number generation + +(define listener (tcp-listen 4326 5 #t)) +(define a (thread (lambda () + (define-values (s-in s-out) (tcp-accept listener)) + ; Discard the request header (up to blank line): + ;(regexp-match #rx"(\r\n|^)\r\n" s-in) + (sleep 10) + (define (echo) + (define input (read-line s-in)) + (displayln input s-out) + (flush-output s-out) + (if (eof-object? input) + (displayln "Done talking\n") + (echo))) + (echo) + (close-input-port s-in) + (close-output-port s-out) + (tcp-close listener) + 'ok))) + +(define t (thread (lambda () + (define-values (c-in c-out) (tcp-connect "localhost" 4326)) + (define input-prompt "input: ") + (define output-prompt "output: ") + + ;; prompt for username and bind to a variable username + (display "What's your name?\n") + (define username (read-line)) + (define usernamei (string-append username ": ")) ;; make username appear nicer in a prompt + (define fair (make-semaphore 1)) + + ;; intelligent read, quits when user types in "quit" + (define (read-loop-i) + ;(semaphore-wait fair) + ; (display usernamei) + (define input (read-line)) + ;; do something over here with input maybe send it out + + ;; Tests input if its a quit then kills all threads + ;; An if would be better here tbh + (cond ((string=? input "quit") (exit))) + (display (string-append output-prompt input "\n") c-out) + (flush-output c-out) + (displayln (read-line c-in)) ;; server echoes back sent input + ;(semaphore-post fair) + (read-loop-i) + ) + (read-loop-i) + 'ok))) + +;(kill-thread a) +;(kill-thread t) +(thread-wait t) +(display "DONE!!\n") + From cb381871d518077649be6272af823dabec2fcd28 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Sun, 9 Apr 2017 22:37:50 -0400 Subject: [PATCH 15/16] reorganized repo a bit better --- client.rkt => Hermes/client.rkt | 0 .../concurrentreadandprint.rkt | 0 server.rkt => Hermes/server.rkt | 0 tcpcommunication.rkt => Hermes/tcpcommunication.rkt | 0 README.md | 4 ++-- FP4-instructions.md => docs/FP4-instructions.md | 0 arch_diagram.png => ext/arch_diagram.png | Bin .../architecture_diagram.png | Bin .../gui/Gui_Exploration.rkt | 0 {feasibility_analysis => tests}/gui/windows.rkt | 0 {feasibility_analysis => tests}/gui/windows2.rkt | 0 {feasibility_analysis => tests}/tcpevents/README.md | 0 crpovertcp.rkt => tests/tcpevents/crpovertcp.rkt | 0 .../tcpevents/server.rkt | 0 .../tcpvanilla/README.md | 0 .../tcpvanilla/client.rkt | 0 .../tcpvanilla/client2.rkt | 0 .../tcpvanilla/server.rkt | 0 .../tcpvanilla/tcptalk.rkt | 0 19 files changed, 2 insertions(+), 2 deletions(-) rename client.rkt => Hermes/client.rkt (100%) rename concurrentreadandprint.rkt => Hermes/concurrentreadandprint.rkt (100%) rename server.rkt => Hermes/server.rkt (100%) rename tcpcommunication.rkt => Hermes/tcpcommunication.rkt (100%) rename FP4-instructions.md => docs/FP4-instructions.md (100%) rename arch_diagram.png => ext/arch_diagram.png (100%) rename architecture_diagram.png => ext/architecture_diagram.png (100%) rename Gui_Exploration.rkt => tests/gui/Gui_Exploration.rkt (100%) rename {feasibility_analysis => tests}/gui/windows.rkt (100%) rename {feasibility_analysis => tests}/gui/windows2.rkt (100%) rename {feasibility_analysis => tests}/tcpevents/README.md (100%) rename crpovertcp.rkt => tests/tcpevents/crpovertcp.rkt (100%) rename {feasibility_analysis => tests}/tcpevents/server.rkt (100%) rename {feasibility_analysis => tests}/tcpvanilla/README.md (100%) rename {feasibility_analysis => tests}/tcpvanilla/client.rkt (100%) rename {feasibility_analysis => tests}/tcpvanilla/client2.rkt (100%) rename {feasibility_analysis => tests}/tcpvanilla/server.rkt (100%) rename {feasibility_analysis => tests}/tcpvanilla/tcptalk.rkt (100%) diff --git a/client.rkt b/Hermes/client.rkt similarity index 100% rename from client.rkt rename to Hermes/client.rkt diff --git a/concurrentreadandprint.rkt b/Hermes/concurrentreadandprint.rkt similarity index 100% rename from concurrentreadandprint.rkt rename to Hermes/concurrentreadandprint.rkt diff --git a/server.rkt b/Hermes/server.rkt similarity index 100% rename from server.rkt rename to Hermes/server.rkt diff --git a/tcpcommunication.rkt b/Hermes/tcpcommunication.rkt similarity index 100% rename from tcpcommunication.rkt rename to Hermes/tcpcommunication.rkt diff --git a/README.md b/README.md index 4b247b0..2807b00 100644 --- a/README.md +++ b/README.md @@ -72,11 +72,11 @@ satisfactorily we would have met our goals. ## Architecture Diagram #### Preliminary design -![Architecture](https://github.com/oplS17projects/Hermes/blob/master/arch_diagram.png) +![Architecture](https://github.com/oplS17projects/Hermes/blob/master/ext/arch_diagram.png) #### The Game plan -![Diagram](https://github.com/oplS17projects/Hermes/blob/master/architecture_diagram.png) +![Diagram](https://github.com/oplS17projects/Hermes/blob/master/ext/architecture_diagram.png) ## Schedule diff --git a/FP4-instructions.md b/docs/FP4-instructions.md similarity index 100% rename from FP4-instructions.md rename to docs/FP4-instructions.md diff --git a/arch_diagram.png b/ext/arch_diagram.png similarity index 100% rename from arch_diagram.png rename to ext/arch_diagram.png diff --git a/architecture_diagram.png b/ext/architecture_diagram.png similarity index 100% rename from architecture_diagram.png rename to ext/architecture_diagram.png diff --git a/Gui_Exploration.rkt b/tests/gui/Gui_Exploration.rkt similarity index 100% rename from Gui_Exploration.rkt rename to tests/gui/Gui_Exploration.rkt diff --git a/feasibility_analysis/gui/windows.rkt b/tests/gui/windows.rkt similarity index 100% rename from feasibility_analysis/gui/windows.rkt rename to tests/gui/windows.rkt diff --git a/feasibility_analysis/gui/windows2.rkt b/tests/gui/windows2.rkt similarity index 100% rename from feasibility_analysis/gui/windows2.rkt rename to tests/gui/windows2.rkt diff --git a/feasibility_analysis/tcpevents/README.md b/tests/tcpevents/README.md similarity index 100% rename from feasibility_analysis/tcpevents/README.md rename to tests/tcpevents/README.md diff --git a/crpovertcp.rkt b/tests/tcpevents/crpovertcp.rkt similarity index 100% rename from crpovertcp.rkt rename to tests/tcpevents/crpovertcp.rkt diff --git a/feasibility_analysis/tcpevents/server.rkt b/tests/tcpevents/server.rkt similarity index 100% rename from feasibility_analysis/tcpevents/server.rkt rename to tests/tcpevents/server.rkt diff --git a/feasibility_analysis/tcpvanilla/README.md b/tests/tcpvanilla/README.md similarity index 100% rename from feasibility_analysis/tcpvanilla/README.md rename to tests/tcpvanilla/README.md diff --git a/feasibility_analysis/tcpvanilla/client.rkt b/tests/tcpvanilla/client.rkt similarity index 100% rename from feasibility_analysis/tcpvanilla/client.rkt rename to tests/tcpvanilla/client.rkt diff --git a/feasibility_analysis/tcpvanilla/client2.rkt b/tests/tcpvanilla/client2.rkt similarity index 100% rename from feasibility_analysis/tcpvanilla/client2.rkt rename to tests/tcpvanilla/client2.rkt diff --git a/feasibility_analysis/tcpvanilla/server.rkt b/tests/tcpvanilla/server.rkt similarity index 100% rename from feasibility_analysis/tcpvanilla/server.rkt rename to tests/tcpvanilla/server.rkt diff --git a/feasibility_analysis/tcpvanilla/tcptalk.rkt b/tests/tcpvanilla/tcptalk.rkt similarity index 100% rename from feasibility_analysis/tcpvanilla/tcptalk.rkt rename to tests/tcpvanilla/tcptalk.rkt From 44c715c55c239495da8f780276866c0041f04139 Mon Sep 17 00:00:00 2001 From: Ibrahim Mkusa Date: Sun, 9 Apr 2017 22:46:18 -0400 Subject: [PATCH 16/16] final polish for release for 0.2 --- Hermes/concurrentreadandprint.rkt | 8 +++----- Hermes/tcpcommunication.rkt | 3 +++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Hermes/concurrentreadandprint.rkt b/Hermes/concurrentreadandprint.rkt index f67f1dd..95d02c1 100644 --- a/Hermes/concurrentreadandprint.rkt +++ b/Hermes/concurrentreadandprint.rkt @@ -1,12 +1,10 @@ #lang racket (require math/base) ;; for random number generation +;; a proof of concept +;; one thread waits for input +;; another displays messages in the background -;; author: Ibrahim Mkusa -;; about: print and read concurrently -;; notes: output may need to be aligned and formatted nicely -;; look into -;; https://docs.racket-lang.org/gui/text-field_.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._text-field~25%29._get-editor%29%29 ;; create custodian for managing all resources ;; so we can shutdown everything at once diff --git a/Hermes/tcpcommunication.rkt b/Hermes/tcpcommunication.rkt index 27a5151..134e697 100644 --- a/Hermes/tcpcommunication.rkt +++ b/Hermes/tcpcommunication.rkt @@ -1,4 +1,7 @@ #lang racket +;; Reads input iteratively then sends it to local server +;; client reads back the message and displays it + (require math/base) ;; for random number generation (define listener (tcp-listen 4326 5 #t))