0

My program:
I create 2 threads:Thread 1 with a listen socket,and thread 2 do somethings.
But thread 1 blocks program and i can not start thread 2 until listen socket on thread 1 receives data. But i need 2 threads run at the same time,and don`t need to keep in sync between 2 threads.(but still in same program).
How to do it??? My code like this:

Thread thread1 = new Thread(new ThreadStart(a.thread1));
Thread thread2 = new Thread(new ThreadStart(b.thread2));
try
            {
                thread1.Start();
                thread2.Start();
                thread1.Join();   // Join both threads with no timeout
                                  // Run both until done.
                thread2.Join();
            }

Program stop at thread 1(listen socket).
And i don't want to use non-blocking socket(I am using blocking socket).
Listen socket should block child thread,but should not block my program.
NoNaMe
  • 6,020
  • 30
  • 82
  • 110
voxter
  • 853
  • 2
  • 14
  • 30

1 Answers1

0

I have just recently had this self same issue and resolved it like this:

    private static void StartServers()
{
    for (int i = Convert.ToInt32(ConfigurationManager.AppSettings.Get("PortStart"));
                    i <= Convert.ToInt32(ConfigurationManager.AppSettings.Get("PortEnd"));
                    i++)
                {
                    var localAddr = IPAddress.Parse(ConfigurationManager.AppSettings.Get("IpAddress"));
                    var server = new TcpListener(localAddr, i);
                    Servers.Add(server);
                    server.Start();
                    StartAccept(server);
                }
}
private static void StartAccept(TcpListener server)
    {
        server.BeginAcceptTcpClient(OnAccept, server);
    }
private static void OnAccept(IAsyncResult res)
    {
        var client = new TcpClient();
        try
        {
            Console.ForegroundColor = Console.ForegroundColor == ConsoleColor.Red
                ? ConsoleColor.Green
                : ConsoleColor.White;
            var server = (TcpListener) res.AsyncState;
            StartAccept(server);
            client = server.EndAcceptTcpClient(res);
            Console.WriteLine("Connected!\n");
            var bytes = new byte[512];
            // Get a stream object for reading and writing
            var stream = client.GetStream();


            int i;

            // Loop to receive all the data sent by the client.
            while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
            {
                // Translate data bytes to a ASCII string.
                var data = Encoding.ASCII.GetString(bytes, 0, i);
                Console.WriteLine("Received: {0} \n", data);

                // Process the data sent by the client.
                data = InterpretMessage(data);
                var msg = Encoding.ASCII.GetBytes(data);

                // Send back a response.
                stream.Write(msg, 0, msg.Length);
                Console.WriteLine("Sent: {0} \n", data);
            }
        }
        catch (Exception exception)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            client.Close();
            Console.WriteLine(exception.Message);
        }
    }

Basically what this does is creates an asynchronous receiving system in which you can have multiple servers listening to multiple ports simultaneously. Bearing in mind that you can only ever have one listener per port.

In your example, you can simply call the StartServers method and then directly afterwards, continue with whatever your application is doing.

In order for this to work for a single server on a single port, merely remove the looping in StartServers and configure 1 TcpListener and start it up.

Vaelen
  • 191
  • 1
  • 11
  • Can`t we use non blocking-Thread for synchronous socket???(only wait-stop 1 process,not program) – voxter Dec 01 '15 at 05:27
  • Isn't the problem that you have right now the fact that your Threads are blocking until the Listener receives data? A synchronous operation with block the thread and hence block the joined thread as well. Perhaps a better question from me should be, why are the Threads joined if they are doing independent work? By Joining both threads are you not possibly creating a race condition? are you trying to do something like [this](https://msdn.microsoft.com/en-us/library/95hbf2ta(v=vs.110).aspx) – Vaelen Dec 01 '15 at 07:02
  • I see:When using Thread1.join() , Program will be blocked until thread1(listen socket) has completed.But if i don`t join thread 1 to program,can i get result of thread???(Thread 1 will change some values for me) – voxter Dec 01 '15 at 09:52
  • Assuming that the class values are either static or your class is a singleton, then yes you should be able to. Keep in mind though that you are no thread safe and you may encounter race conditions if your blocking strategy is wrong. As you can see from the example in the link, the program will wait until thread 2 finishes, essentially any changes made to shared data by thread 1 should be available to thread 2. – Vaelen Dec 02 '15 at 03:26