(struct tcp-channel (source destination subpacket) #:prefab) source : TcpAddress destination : TcpAddress subpacket : TcpSubPacket
a tcp-address, representing a remote socket;
a tcp-handle, representing a local socket on a kernel-assigned port; or
a tcp-listener, representing a local socket on a user-assigned port.
The id must be chosen carefully: it is scoped to the local VM, i.e. shared between processes in that VM, so processes must make sure not to accidentally clash in handle ID selection. They are also used in TcpChannel to mean a specific instance of a TCP connection, so if you are likely to want to reconnect individual flows, use different values for id.
Choose a tcp-handle, and then create endpoints as follows:
(let ((local (tcp-handle 'some-unique-value)) (remote (tcp-address "the.remote.host.example.com" 5999))) (transition/no-state (publisher (tcp-channel local remote ?)) (subscriber (tcp-channel remote local ?) (on-message [(tcp-channel _ _ (? eof-object?)) ; Handle a received end-of-file object (transition ...)] [(tcp-channel _ _ (? bytes? data)) ; Handle received data (transition ...)]))))
The TCP driver will automatically create an outbound connection in response to the presence of the endpoints. When the endpoints are deleted (or the process exits), the TCP driver will notice the absence and will close the underlying TCP socket.
For a complete example, see TCP chat client.
Choose a port number, and then create an observer endpoint as follows:
(observe-publishers (tcp-channel ? (tcp-listener 5999) ?) (match-conversation (tcp-channel them us _) (on-presence (spawn (chat-session them us)))))
The use of observe-publishers here indicates that this endpoint isn’t actually interested in exchanging any TCP data; instead, it is monitoring demand for such exchanges. The TCP driver uses the unusual 'everything InterestType to monitor the presence of 'observers, and creates listening TCP server sockets in response. When a connection comes in, the TCP driver spawns a manager process which offers regular 'participant endpoints for communicating on the newly-arrived socket.
To illustrate the code for handling a newly-arrived connection,
(define (chat-session them us) (transition/no-state (subscriber (tcp-channel them us ?) (on-absence (quit)) (on-message [(tcp-channel _ _ (? bytes? data)) ; Handle incoming data (transition ...)]))))
TCP-related messages will be of the form
(tcp-channel remote-address local-address subpacket)
Send data with
For examples of the use of the timer driver, see uses of set-timer and timer-expired in the Marketplace-based DNS resolver.
For examples of the use of the UDP driver, see uses of udp-packet etc. in the Marketplace-based DNS resolver.