Reputation: 453
I'm a beginner trying to understand TCP, and I'm using Rust. If I create a new listener and bind it to an address
let tcplistener = TcpListener::bind("127.0.0.1:55555").unwrap();
I can tcplistener.accept()
new connections between 127.0.0.1:55555
and some other endpoint on the client.
In my case, tcplistener
lives within an instance of a struct representing a plugin. Each plugin should be controllable from its own browser tab. There is one connection (endpoint-pair) per plugin, with one endpoint always being 127.0.0.1:55555
. The plugins run in a single thread with non-blocking listeners and streams. I use websockets, but I'm not sure if this question is specific to websockets.
What I'm doing now is
tcplistener
field in plugin A to a newly created listener with arbitrary OS-assigned portThis seems to work; if I instantiate a new plugin B afterwards, I can create a listener bound to 127.0.0.1:55555
and accepting a connection. If I don't create a new listener with different address/port, then I get the "Address already in use" error.
This is obviously not a good solution since it occupies all the other ports for no reason. Is there a better way?
A comment said:
Why does each plugin have a
TcpListener
? Why not have one component with the listener, callaccept
, then hand off the returnedTcpStream
to each constructed plugin?
That does sound good, but where would that TcpListener
be stored, and how does it hand off the streams? Possibilities I see for storing:
Upvotes: 1
Views: 563
Reputation: 431369
One workaround, if I understand all of your limitations correctly, is to use Option
. Option
is used for precisely the case of "something or not something".
Here, you could have an Option<TcpListener>
. On a freshly-initialized plugin, this would be set to Some(...)
, and once accepted, would transition to None
.
This does have a number of downsides:
None
.Some kind of parent-child relationship is probably better, or even limiting to a singleton plugin, if plausible.
Upvotes: 1