简体   繁体   English

多线程UDP客户端/服务器C#

[英]Multithreaded UDP client/server C#

I am trying to get a multi-threaded UDP client/server going, but i'm running into problems on the server side. 我正在尝试使用多线程UDP客户端/服务器,但是我在服务器端遇到了问题。 When a client attempts to register, a thread is created and all the interactions for that client are handled in that thread, but for some reason it only enters the thread once then exits right away.. can anyone help figure out why this happens? 当客户端尝试注册时,将创建一个线程,并在该线程中处理该客户端的所有交互,但是由于某种原因,它仅进入该线程一次,然后立即退出。 -Thanks in advance.. -提前致谢..

namespace AuctionServer
{
   class Program
   {
    public static Hashtable clientsList = new Hashtable();

    static void Main(string[] args)
    {
        //IPAddress ipAd = IPAddress.Parse("255.255.255.255");
        UdpClient server = new UdpClient(8888);
        IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
        string data = "";
        int listSize = 0;
        Console.WriteLine("Auction Server Started ....");
        listSize = clientsList.Count;

        while (true)
        {
            //Reads data
            byte[] inStream = server.Receive(ref remoteEndPoint);
            data = Encoding.ASCII.GetString(inStream);
            //Console.WriteLine("REGISTER " + remoteEndPoint);

            if (!data.Contains("DEREGISTER "))
            {
                byte[] sendBytes = Encoding.ASCII.GetBytes(data + remoteEndPoint.ToString());
                server.Send(sendBytes, sendBytes.Length, remoteEndPoint);
                handleClinet client = new handleClinet();
                Console.WriteLine(data);
                clientsList.Add(data, server);
                client.startClient(server, data, clientsList, remoteEndPoint);
                data = "";
            }
        }
    }

    //Broadcast method is used to send message to ALL clients
    public static void broadcast(UdpClient dest, string msg, string uName, bool flag, IPEndPoint sendEP, Hashtable clientsList)
    {
        foreach (DictionaryEntry Item in clientsList)
        {
            Byte[] broadcastBytes = null;

            if (flag == true)
            {
                broadcastBytes = Encoding.ASCII.GetBytes(msg);
            }
            else
            {
                broadcastBytes = Encoding.ASCII.GetBytes(msg);
            }
            dest.Send(broadcastBytes, broadcastBytes.Length, sendEP);

        }
    }
}//end Main class

} }

namespace AuctionServer
{
public class handleClinet
{
    UdpClient clientSocket;
    string clNo;
    Hashtable clientsList;
    IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, 0);
    IPEndPoint myEP = new IPEndPoint(IPAddress.Any, 0);

    public void startClient(UdpClient inClientSocket, string clineNo, Hashtable cList, IPEndPoint tempEP)
    {
        this.myEP = tempEP;
        this.clientSocket = inClientSocket;
        this.clNo = clineNo;
        this.clientsList = cList;
        Thread ctThread = new Thread(doChat);
        ctThread.Start();
    }

    private void doChat()
    {
        int requestCount = 0;
        byte[] bytesFrom = new byte[10025];
        string dataFromClient = null;
        string rCount = null;
        requestCount = 0;

        while ((true))
        {
            try
            {
                //Thread.Sleep(1000);
                if (requestCount == 0)
                {
                    Console.WriteLine("Thread Created");
                    requestCount++;
                }
                byte[] received = clientSocket.Receive(ref remoteIPEndPoint);
                dataFromClient = Encoding.ASCII.GetString(received);
                Console.WriteLine(dataFromClient);

                if (dataFromClient.Contains("DEREGISTER"))
                    clientSocket.Send(received, received.Length, remoteIPEndPoint);
                    //Program.broadcast(clientSocket, "DREG-CONF", clNo, true, myEP, clientsList);
                //else
                //    Program.broadcast(clientSocket, dataFromClient, clNo, true, myEP, clientsList);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadKey();
                break;
            }
        }//end while
    }//end doChat

} }

The two loops run on different threads. 这两个循环在不同的线程上运行。 So the loop in Main() is executing concurrently with the loop in your handleClinet class. 因此, Main()中的循环与handleClinet类中的循环同时执行。

If you want to switch to the handleClinet class's loop and debug it, then use the Threads window in the debugger ( Debug menu, Windows menu item, then Threads ...or press Ctrl - D , T ) to switch to that thread. 如果要切换到handleClinet类的循环并对其进行调试,请使用调试器中的“ Threads窗口(“ Debug菜单, Windows菜单项,然后是“ Threads ...”或按Ctrl - DT )切换到该线程。 Then you can see the call stack and state of that thread. 然后,您可以看到该线程的调用堆栈和状态。

Note that this may not work on the Express version of Visual Studio. 请注意,这可能不适用于Visual Studio的Express版本。 I haven't tried the most recent version, but past versions did not support the Threads window. 我尚未尝试使用最新版本,但过去的版本不支持“ Threads窗口。 (You can still debug a specific thread by setting a breakpoint there…it's just that you can't switch to the thread manually). (您仍然可以通过在此处设置断点来调试特定线程……只是您无法手动切换到该线程)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM