Help implementing multithreading in a distributed system, please?
I got a distributed system, meaning one solution that's a server and two which are clients. The objective is to use threads so that more than one client can communicate over TCP with the server simultaneously. I was told that I need to make it so there is some kind of code that makes it so different clients connect through different ports or the communication won't go well, but I really don't know. Any help you can give me? I know this isn't much to go on, but I'm trying to figure it out myself and feel free to ask questions and I'll do my best to answer.
29 Replies
what you probably want to do is have a listener loop whose job is to accept new clients and hand that connection off to individual threads/tasks for each client
all your clients can connect to the same port on the server
i don't recommend using plain threads, the task/async APIs are good for this
Right now, I'm connecting by using on the client side:
I imagine I should use a constructor that just sends over the IP and not the port?
On the server side:
no, the client still needs to know the port on the server
but you don't need different ports for different clients
TcpListener should have an
Accept
method that waits for a new connection then returns an object representing the connection to that client
also use the async versions of methods if you can, here's an example from a similar project i have using plain Socket
s instead of TcpListener
where HandleStation
is the method responsible for communicating with a single clientlistener has an AcceptTCPClient() method, which I am already using. Looking at the documentation there seems to also be no method named just Accept, however there are AcceptSocket(), AcceptSocketAsync() and AcceptTCPClientAsync()...
TcpClient is just a thin wrapper around Socket
I think I already have the barebones of a listener loop similar to what you describe but it seems unfinished:
yeah, i wouldn't use raw threads though
it'll work but tasks are the more modern way to do it
my teacher may want me to though, idk
he does specifically talk about threads not tasks
rip, just do it the crusty way then
and keep in mind it's not how you should actually do it 😛
tbf, I don't know that's what he wants, I'll have to ask him tomorrow
but dos that loop do what I need?
Like, is it connecting different clients to different ports?
you don't need different ports to accept multiple clients
So, will it be able to successfully talk to different clients at the same time?
yes
$tias
technically though, if it's not on different ports it ends up being async but not parallel I think? No two clients could really send at the same time, it'd have to 'wait' for one to finish before you could get the next message. If they specified that you need to use different ports, that may not be what you want. Though it's not at all typical in the real world to specify different ports or truly parallelize it, and what Jim's saying would be the real world solution - but if it's a class and a teacher telling you to do it, you better do what they say
But if you need it on different ports and in parallel, just run two instances of the app with two different settings
What would you consider proof that the communication is going well? I mean both solutions are firing fine and it seems to be saving the two clientID values simultaneously in a List like I programmed it to. In the debugger, in the parallell stacks view there seems to be two paralell threads taking place at the same time. Further testing is a little hard because the way this communication is fully completed is through editing of files, which I can't allow yet because of the problems with two threads accessing the same resource. I have to implement a mutex adequately (which I'll also need help with btw 😆 )
The two ports thing is because I asked a colleague of mine for advice and that's what he told me, but that's just how he did it
if it's all in the same app, a SemaphoreSlim would do the job, no need for a mutex (but mutex prob works too)
Now I don't think the two ports thing is necessary, the teacher didnt say nothing about that
I just thought that was the only way because I'm still learning
the mutex thing on the other hand is a specific requirement
the main thing is just to use async. Use that everywhere, and it's all done
"I was told that I need to make it so there is some kind of code that makes it so different clients connect through different ports or the communication won't go well" is non-sense. Typical web servers
(like Kestrel) work at a single port (like 80) very well with multiple clients.
While you can always roll out your own framework via trials, you really analyze existing libraries/frameworks (Kestrel/SuperSockets) to understand their design and how they properly use threads.
Thanks :Ok: I was told that different ports thing by a 20 year old CS student that is figuring this stuff out on his own and even then that's just my also very inexperienced interpretation of what he tried to sum up in 30 seconds, so I definitely wasn't taking it as an authoritative assessment at all, which is why I brought it up here for scrutiny.
Is this relevant for my case? This isn't a web application, at least not in the conventional sense, it's supposed to mimic a very simple distributed system. Not saying it isn't, I just really don't know enough to judge
Also, it's a specific requirement of this project that we only use System* .NET framework libraries, so would studying those other libs/frameworks really be helpful? Again, not a rhetorical question, I actually don't know
if the assignment is to do something with raw TCP connections then those libraries won't be helpful to you
in my experience school assignments are best done exactly how the teacher wants them then learn actual good practices outside of school
Study the right way to use threads, and then you can apply the same pattern(s) to your project. There might be simpler samples, but frameworks used by production apps are clearly better source of information.
Ok, so about the mutex implementation. This is a recreation of what I have:
will that work? Just looks really simple. It's really important that I can be sure and preferably demonstrate that access is being restricted and managed appropriately between all the different concurrent threads. @Lex Li @Jimmacle
to make everything async, wouldn't I need to be working with and returning tasks? I can't use Tasks, teacher's orders :weirdChamp:
a whole mutex is probably unnecessary,
SemaphoreSlim
is enough if you want to control concurrent access to a resource in the same process
is a literal Mutex
a requirement?Yes, the teacher specifically talked about it repeatedly and it's all over the project protocol so yeah. I think in the second part of this project he's gonna want us to do more fancy stuff with shared resources which is why we're using Mutex despite it being overkill
man i hate school CS curriculum
in that case what you have is fine
please elaborate :Hmm:
it's almost always outdated and teaching weird practices that you wouldn't normally use