2

I'm trying to understand multi-threading in TCP so I'm coding a basic telnet text "router".

using ReadLine() each thread using a TCP listener will wait for input from the telnet client and then respond based on the text which is sent. I have this working with multiple threads and multiple telnet clients.

I want to conditionally send messages to all threads. For example, if the text sent from any one thread is "Alert!" then I want every thread for connected clients to execute WriteLine("Alert!")

Does this make sense? My problem is that I don't know how to make one thread raise an event in another thread.

Matthew
  • 10,244
  • 5
  • 49
  • 104

2 Answers2

1

You need to look at a Event Broker pattern. Basically you would have one object with an event that all your threads subscribe to. It will also have a method that can be called which will invoke the event. It maybe sounds complicated, but its fairly simple.

Example code is here http://msforge.net/blogs/paki/archive/2007/11/20/EventBroker-implementation-in-C_2300_-full-source-code.aspx.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Pauli Østerø
  • 6,878
  • 2
  • 31
  • 48
  • Yes, this is a great start, thanks! Now there is the next issue of executing writeline for each thread... – Matthew Dec 14 '10 at 23:34
  • 1
    that should be easy enough to do inside the eventhandler that is subscribing to the event. – Pauli Østerø Dec 14 '10 at 23:57
  • Any pointers? The problem is that the telnet sessions are basically sitting around on `readline`... how would I execute a `writeline` in this same socket from an eventhandler? I'm thinking I may have to create static sockets? – Matthew Dec 15 '10 at 00:04
  • good point... one way is to make your ReadLine() call inside a while loop that can be interrupted, kinda like while(noEvents) instead of while(true). that way you can set noEvents = false when you an event is fired, which will break your loop so you are able to call WriteLine, and after that you set noEvents back to true and go back to your loop. – Pauli Østerø Dec 15 '10 at 00:25
  • Ok, so I can't interrupt the `ReadLine()` because the loop never proceeds past it to the `while(noEvents)`..... The way I solved it was by exposing the `StreamWriter` to another thread, which can write all it wants regardless of the fact that the `StreamReader` is stuck – Matthew Dec 16 '10 at 18:40
  • ah, so the execution actually stops on ReadLine... makes sense... i though it was a while loop that kept running and calling ReadLine for each iteration. you solution makes more sense then, to call have access to the StreamWrite so you call methods on it from the eventhandler. – Pauli Østerø Dec 17 '10 at 19:25
0

Don't think of threads as data. Think of them as constructs.

Obviously to have class A raise an event in class B, B must reference A and subscribe to its event.

But honestly, I think you are going about it the wrong way. Have a single TCP listener. When a message comes in, you'll get a web request object and you can process in its own thread. When processing the thread, if you find word "Alert", generate an event to a higher level class. Then handle the event and do whatever needs to be done. Example architecture:

Manager instantiates TcpHandler and subscribes to its AlertReceived event. TcpHandler instantiates MessageProcessor and subscribes to its MessageReceived event.

When TcpHandler reads something off its TcpListener object, fire off the MessageProcessor class and have it read the actual data on another thread.

Fire the MessageReceived event. Then in the TcpHandler class, handle the event. If the data received is "Alert", fire the AlertReceived event.

The Manager class will catch the event and do whatever else you then desire.

AngryHacker
  • 59,598
  • 102
  • 325
  • 594
  • if you're running a telnet session, you need to keep the connection open and talking to each client has to be done in its own thread. n number of clients equals n number of threads with each its own listener that waits for input from the client. – Pauli Østerø Dec 14 '10 at 02:23