• 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.
  • Posts

    • I'd concur too, as an informed enthusiast I'd find it a good deal, but your average Joe just wants cheap as possible and it's hard to beat Amazon or Ebay builds for that.
    • Now you know how many would-be Windows 11 users felt. I’m not justifying any of it, but MS and Apple both do it.
    • An Air India plane with 242 people on board crashed Thursday near a major international airport in the western Indian city of Ahmedabad, the airline and the country's government said. https://www.nbcnews.com/world/asia/air-india-plane-crashes-indias-ahmedabad-airport-rcna212545
    • NTLite 2025.06.10473 by Razvan Serea NTLite is a Windows configuration tool that allows you to modify your existing Windows install or an image yet to be deployed, remove Windows components, configure and integrate, speed up the Windows deployment process. Reduce Windows footprint on your RAM and storage drive memory. Remove components of your choice, guarded by compatibility safety mechanisms, which speed up finding that sweet spot. Windows Unattended feature support, providing many commonly used options on a single page for easy setup. Easily integrate a single or multiple drivers, update or language packages. Package integration features smart sorting, enabling you to seamlessly add packages for integration and the tool will apply them in the appropriate order, keeping hotfix compatibility in check. One of the important new features of NTLite (compared to its predecessors) is the ability to modify an already installed the operating system, by removing unnecessary components. Supports Windows 11, 10, 8.1 and 7, x86 and x64, live and image. Server editions of the same versions, excluding support for component removals and feature configuration. ARM64 image support in the alpha stage. Does not support Checked/Debug, Embedded, IoT editions, nor Vista or XP. NTLite 2025.06.10473 changelog: Upgrade UI: Text size now set as host, more readable on some systems Post-setup: Loading progress improvement for the 99% delay Components: ‘Snipping tool’ compatibility option UI-Translation: Thanks for Romanian (Coman) Fix Updates: Parallel WinRE integration getting stuck Updates: Download overwrite previous Defender updates Settings: Win10 News widget disabling Download: NTLite 64-bit | 21.5 MB (Free, paid upgrade available) Download: NTLite 32-bit | 19.3 MB Link: NTLite Home Page | NTLite Features | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
  • Recent Achievements

    • Week One Done
      elsafaacompany earned a badge
      Week One Done
    • Week One Done
      Yianis earned a badge
      Week One Done
    • Veteran
      Travesty went up a rank
      Veteran
    • One Month Later
      somar86 earned a badge
      One Month Later
    • Week One Done
      somar86 earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      506
    2. 2
      ATLien_0
      258
    3. 3
      +FloatingFatMan
      183
    4. 4
      +Edouard
      180
    5. 5
      snowy owl
      131
  • Tell a friend

    Love Neowin? Tell a friend!