Re: [racket-users] Debug help with Unix Write
On Feb 12, 2016, at 1:24 PM, Ty Coghlan wrote: > As part of a course I'm in, we had to write a simple bridge simulation that > could handle data messages to and from unix ports that have attached to them > several hosts. In addition, these bridges have to implement a simple spanning > tree algorithm, and send and receive BPDU messages. These messages are all > formatted in JSON. My partner and I went about designing this in racket, > changing the port protocol from SOCK_STREAM to SOCK_SEQPACKET (changing the > binding of the variable from 1 to 5) in the unix library: > https://github.com/racket/unix-socket. > > We ran into the problem where we were able to read messages from the hosts > attached to the unix sockets, however, we could not read messages that we had > sent out (which through the simulation get bounced back to the bridge so we > can set up the spanning tree). This lead us to believe that there is a bug in > how we write data to the unix socket, and we spent so long debugging it that > we eventually just rewrote the program in python to make in before the > deadline. > > All outgoing messages are written by a function called broadcast: > > (define (broadcast source destination type message port) > (write-json (hash 'source source 'destination destination >'type type 'message message) > port)) Consider flushing the output port here. (I just wrote a function like this for my class project.) (Also use newline to separate messages.) > > It takes a string source, destination, message type, message, and finally an > output port to write them on. Then it just wraps them up in a hash table and > writes them to the port. We attempted to use display, print, regular write, > and none of them alleviated the problem. We then looked at everything that > passes data to broadcast, which includes the bpdu function > > (define (bpdu bridge-id root-id cost-to-root lans) > (for ([lan (hash-values lans)]) >(broadcast bridge-id "" "bpdu" > (jsexpr->string (hash 'id bridge-id 'root root-id 'cost > cost-to-root)) > (cadr lan > > bpdu takes in the current bridge-id, root-id, cost-to-root, and all lans > (where lans are a three element list of lan id, out-port, and in-port), and > simply formats them as a string before passing it as the message argument in > broadcast to every port. This bpdu message is called from our main function, > which sets up the unix socket connections and continuously loops, sending > bpdus every 500ms. The full (messy) file can be seen at > https://github.com/cdris/bridges/blob/master/3700bridge.rkt. > > Any help would be immensely appreciated. > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Debug help with Unix Write
Unix socket ports are block-buffered, so after writing to them you need to flush the output. Something like (write-json data port) (flush-output port) Your code on github has calls to flush-output without the port argument. That doesn't flush the unix socket port; it flushes the current output port (usually the console or DrRacket) instead---and those ports are line-buffered anyway. That's my best guess about the problem you saw. BTW, even after that issue, I would worry about how Racket's IO system interacts with SOCK_SEQPACKET sockets. Specifically, I think you might lose data if a packet is larger than some internal buffer used by Racket. From "man socket": SOCK_SEQPACKET sockets employ the same system calls as SOCK_STREAM sockets. The only difference is that read(2) calls will return only the amount of data requested, and any data remaining in the arriving packet will be discarded. Ryan On 02/12/2016 01:24 PM, Ty Coghlan wrote: As part of a course I'm in, we had to write a simple bridge simulation that could handle data messages to and from unix ports that have attached to them several hosts. In addition, these bridges have to implement a simple spanning tree algorithm, and send and receive BPDU messages. These messages are all formatted in JSON. My partner and I went about designing this in racket, changing the port protocol from SOCK_STREAM to SOCK_SEQPACKET (changing the binding of the variable from 1 to 5) in the unix library: https://github.com/racket/unix-socket. We ran into the problem where we were able to read messages from the hosts attached to the unix sockets, however, we could not read messages that we had sent out (which through the simulation get bounced back to the bridge so we can set up the spanning tree). This lead us to believe that there is a bug in how we write data to the unix socket, and we spent so long debugging it that we eventually just rewrote the program in python to make in before the deadline. All outgoing messages are written by a function called broadcast: (define (broadcast source destination type message port) (write-json (hash 'source source 'destination destination 'type type 'message message) port)) It takes a string source, destination, message type, message, and finally an output port to write them on. Then it just wraps them up in a hash table and writes them to the port. We attempted to use display, print, regular write, and none of them alleviated the problem. We then looked at everything that passes data to broadcast, which includes the bpdu function (define (bpdu bridge-id root-id cost-to-root lans) (for ([lan (hash-values lans)]) (broadcast bridge-id "" "bpdu" (jsexpr->string (hash 'id bridge-id 'root root-id 'cost cost-to-root)) (cadr lan bpdu takes in the current bridge-id, root-id, cost-to-root, and all lans (where lans are a three element list of lan id, out-port, and in-port), and simply formats them as a string before passing it as the message argument in broadcast to every port. This bpdu message is called from our main function, which sets up the unix socket connections and continuously loops, sending bpdus every 500ms. The full (messy) file can be seen at https://github.com/cdris/bridges/blob/master/3700bridge.rkt. Any help would be immensely appreciated. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Debug help with Unix Write
As part of a course I'm in, we had to write a simple bridge simulation that could handle data messages to and from unix ports that have attached to them several hosts. In addition, these bridges have to implement a simple spanning tree algorithm, and send and receive BPDU messages. These messages are all formatted in JSON. My partner and I went about designing this in racket, changing the port protocol from SOCK_STREAM to SOCK_SEQPACKET (changing the binding of the variable from 1 to 5) in the unix library: https://github.com/racket/unix-socket. We ran into the problem where we were able to read messages from the hosts attached to the unix sockets, however, we could not read messages that we had sent out (which through the simulation get bounced back to the bridge so we can set up the spanning tree). This lead us to believe that there is a bug in how we write data to the unix socket, and we spent so long debugging it that we eventually just rewrote the program in python to make in before the deadline. All outgoing messages are written by a function called broadcast: (define (broadcast source destination type message port) (write-json (hash 'source source 'destination destination 'type type 'message message) port)) It takes a string source, destination, message type, message, and finally an output port to write them on. Then it just wraps them up in a hash table and writes them to the port. We attempted to use display, print, regular write, and none of them alleviated the problem. We then looked at everything that passes data to broadcast, which includes the bpdu function (define (bpdu bridge-id root-id cost-to-root lans) (for ([lan (hash-values lans)]) (broadcast bridge-id "" "bpdu" (jsexpr->string (hash 'id bridge-id 'root root-id 'cost cost-to-root)) (cadr lan bpdu takes in the current bridge-id, root-id, cost-to-root, and all lans (where lans are a three element list of lan id, out-port, and in-port), and simply formats them as a string before passing it as the message argument in broadcast to every port. This bpdu message is called from our main function, which sets up the unix socket connections and continuously loops, sending bpdus every 500ms. The full (messy) file can be seen at https://github.com/cdris/bridges/blob/master/3700bridge.rkt. Any help would be immensely appreciated. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.