Add net.tcp.connect and return bound port from net.tcp.listen #475
Labels
No labels
bug
dependencies
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
refactor
rust
technical-debt
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
navicore/patch-seq#475
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
net.tcp.*exposes only the server side:listen,accept,read,write,close. There is no way for a Seq program to initiate a TCP connection. UDP got this right (net.udp.send-to); TCP did not.Two gaps, both small:
1. Missing
net.tcp.connectProposed signature, symmetric with
net.udp.send-tohost/port shape:On success the returned
Socketis interchangeable with one returned bynet.tcp.accept— sameread/write/closesemantics. On failure:(0, false)matching the existing TCP convention.2.
net.tcp.listenshould return the bound portCurrent:
Compare UDP, which already does the right thing:
Requesting
port = 0lets the OS pick an ephemeral port, but with the current TCP signature there is no way to discover what port was assigned. This makes loopback self-tests effectively impossible without hard-coding a port (and racing).Proposed:
For non-zero
port,bound == port. Forport == 0,boundis the OS-assigned port. Matches the UDP convention exactly.Motivation
Seqlings chapter 26 ("TCP") currently has five exercises that all amount to
# I AM NOT DONE+true test.assert. The user is asked to "trace through the pattern mentally." This is because, without a client API and without a discoverable bound port, there is no way to actually run a server-and-client round-trip purely in Seq. The capstone05-echoshows anecho-handlerbody in a comment and never invokes it.By chapter 26 the seqlings user has already done
strand.spawn(ch 24), channels (ch 25), and is more than ready for a working loopback echo as the capstone — but the language won't let them. Onceconnectexists andlistenreturns the bound port, the rework writes itself:Notes
listen/acceptalready does outbound TCP internally —connectis a small addition.udp.bindalready returnsSocket Int Bool, so the precedent for the three-value listen return is in-tree.Scope narrowing —
net.tcp.connectis done and shipped (thank you!). What remains in this issue is the second ask:net.tcp.listenshould return the bound port, symmetric withnet.udp.bind's( Int -- Socket Int Bool ). Currentlylistenreturns( Socket Bool ), which meansport = 0(let the OS pick) leaves the caller with no way to discover what port was assigned.Practical impact: I just reworked seqlings chapter 26 to run real client/server programs, and had to hard-code ports 18261-18265 per exercise because loopback self-tests can't use ephemeral ports. Works fine in practice on single-user dev machines; would collide on shared CI. Not blocking, but the asymmetry with UDP is the only thing in this issue still open.
Suggested signature change:
For non-zero
port,bound == port. Forport == 0,boundis the OS-assigned port. Same convention as UDP.#485