• 0

[C#] Example of Multi-threaded TCPListener?


Question

Hey guys, does anyone happen to know of an example of doing an Asynchronous TCPListener? I feel like I've googled for every variation of socket / TCPClient/multithreaded/etc known to man and I'm going to go nuts soon. :p Basically, I need to have a TCPListener (or just a socket I spose) listening for TCP connections that won't block the GUI, and it can handle multi-connections.

I was trying to do it manually, but I seem to be getting stuck.

http://msdn2.microsoft.com/en-us/library/s...ttcpclient.aspx

Supposedly you begin with those 2 functions above, and supposedly I should be invoking it via a delegate (huh? :\) but theres nothing in the documentation that mentions a delegate. Atm I'm calling it like thus,

			TcpListener Test = new TcpListener(new IPEndPoint(IPAddress.Any, 9000));
			Test.Start();
			DoBeginAcceptTcpClient(Test);

But it seems to get stuck on the "Console.WriteLine("Waiting for a connection...");" line.. which is kinda strange since I thought BeginAcceptTCPClient was supposed to be non-blocking. Sounds like those two functions need to be called from inside their own thread. :s

I dunno.. a link to an example or various kicks in the right direction would be awesome. :( This is like the least important part of my project and I've been stuck on it for ages. :(

9 answers to this question

Recommended Posts

  • 0
  azcodemonkey said:
I'm confused by what you're asking. That example does process the client connections asychronously. It's going to sit at that Console.WriteLine until it receives a connection. It's not blocking anything. It's a server. It waits and serves. :)

But it blocks the GUI thread though. :\ I have those above three lines in Form_Load and the gui never appears. Should I be calling it from a seperate thread? :s

If I remove the WaitOne line it works alright.. but is that a no no? :) I don't see why I would want the main thread to stop to wait for someone to connect. :s

  • 0
  JamesCherrill said:
Sounds like that to me too. What else would you expect?

Someone said that I don't need to do 'DoBeginAcceptTcpClient(Test)' since it would get called by a delegate instead... but as far as I can understand delegates don't create a new thread, so I guess so. :wacko:

  • 0
  Pc_Madness said:
Someone said that I don't need to do 'DoBeginAcceptTcpClient(Test)' since it would get called by a delegate instead... but as far as I can understand delegates don't create a new thread, so I guess so. :wacko:

Delegates are in essence just type-safe function pointers. I'm still confused as to why your server is blocking your gui. Does your server have a gui, or is your client request blocking your client gui?

  • 0

Here's a quick example. There are better implementations of entire servers out there, but it's a start.

	public partial class Form1 : Form
	{
		private Thread serverThread;
		private TcpListener listener;
		public Form1()
		  {
			InitializeComponent();
		}

		private void button1_Click(object sender, EventArgs e)
		{
			serverThread = new Thread(new ThreadStart(StartServer));
			serverThread.Start();
		}

		protected void StartServer()
		{

			listener = new TcpListener(new IPEndPoint(IPAddress.Any, 9000));
			listener.Start();
			while (true)
			{
				Socket socket = listener.AcceptSocket();
								// you'll need some more thread stuff down here.
				if(socket.Connected)
				{

				}

			}
		}

		private void button2_Click(object sender, EventArgs e)
		{
			// stop stuff here
		}
	}

  • 0
  azcodemonkey said:
Delegates are in essence just type-safe function pointers. I'm still confused as to why your server is blocking your gui. Does your server have a gui, or is your client request blocking your client gui?

Nope, this happens before I've even got a client running. :p And yes, my server has a GUI. :p (its a peer 2 peer program so there has to be :p)

  • 0

Sorry bout the late reply, been busy with work.. plus the time has helped clear my head alittle. :)

Ok, just to make sure I've got a good understanding of where to go from here, working with sbauer's code,

if(socket.Connected)
{
   AnotherThread = new Thread(new ThreadStart(RecieveData(socket)));
   AnotherThread.Start();
}

protected void RecieveData(Socket ClientSocket)
{
	while (true)
	{  
		ClientSocket.Recieve(Bufferfellarhere);
		if(EOF Message in string)
		{
			ProcessCommand(MyMessageString);
		}
	}
}

Ok, so, to manage all of these (connected client) threads I would be best off doing an arraylist to hold the threads in?

Or alternatively, could I make a class which is something like,

ClassClient

Thread ClientThread

Socket Client Socket

ClassClient(Socket FromMyConnectFunction)

RecieveData()

SendData()

ProcessCommand()???

Disconnect()

//perhaps some other random things?

So instead of creating the new thread in the TCPListener thread I create it inside the Class constructor of ClassClient, which means I don't have to worry about managing the threads.

So that also means I can have an ArrayList of ClassClient which can be accessed by..the TCPListener thread? But it won't be accessible by the GUI thread? so I won't just be able to do MyArrayList[0].SendData("blah");? And I spose its the same problem with getting Data out of RecieveData. Do I have to go back to the TCPListener Thread and then back to the GUI or can I call the GUI thread directly somehow? Or is it that non-gui threads can interact with each other but you can't fiddle with a gui thread from a non-gui thread?

And I spose this question doesn't matter as much.. but I'm going to have a function called ProcessCommand which will probably convert the recieved data into a nice little class with an array of arguments and source ip etc etc, and then it will look at what kind of command it is and decide what to do (some kind of GUI related action of send data back etc). Would I be best off including that inside the ClassClient (multiple copies of a fairly large function = yuck?) or passing it back into TCPListener somehow or pass the data to the GUI thread and let it handle it?

Also...I think I saw in an example somewhere where they had a try catch inside the Recieve block and they could check if a client had disconnect/socket was closed. I can do that yes to check if a client has closed without sending a disconnect message? :)

I dunno.. am I on the right track here or should I be taken outside and shot? Where one thread starts and one thread ends and getting data between them is screwing with my head. :( Hopefully some of my ramblings make sense to someone. :p

Edited by Pc_Madness
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.