【问题标题】:Multithreaded UDP client/server C#多线程 UDP 客户端/服务器 C#
【发布时间】:2015-01-09 16:24:42
【问题描述】:

我正在尝试让多线程 UDP 客户端/服务器运行,但我在服务器端遇到了问题。当客户端尝试注册时,会创建一个线程,并且该客户端的所有交互都在该线程中处理,但由于某种原因,它只进入线程一次然后立即退出..谁能帮助弄清楚为什么会发生这种情况? -提前谢谢..

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

}

【问题讨论】:

  • 您在 `Console.WriteLine(ex.ToString());` 处是否遇到任何异常?
  • 我没有例外,代码卡在 Program.cs while 循环中,而不是一直在线程的 while 循环中。@MarkSegal

标签: c# network-programming udp client server


【解决方案1】:

这两个循环在不同的线程上运行。所以Main() 中的循环与handleClinet 类中的循环同时执行。

如果你想切换到handleClinet类的循环并调试它,然后使用调试器中的Threads窗口(@98​​7654325@菜单,Windows菜单项,然后Threads...或按Ctrl-D, T) 切换到该线程。然后你就可以看到那个线程的调用栈和状态了。

请注意,这可能不适用于 Visual Studio 的 Express 版本。我还没有尝试过最新版本,但过去的版本不支持Threads 窗口。 (您仍然可以通过在此处设置断点来调试特定线程……只是您无法手动切换到该线程。

【讨论】:

  • 我已经调试过了,但我似乎无法找出问题所在。我希望当客户端向服务器发送“注册”命令时,服务器为该客户端创建一个线程并处理该线程中的通信。这可能吗? @PeterDuniho
  • 我看不出这与哪些线程正在运行的问题有什么关系。但是不,如果线程使用在其他线程中使用的同一个套接字,则不会。正如我在回答您之前的问题时所解释的那样,如果您有两个不同的线程从同一个套接字读取,则您无法控制哪个线程读取哪个消息。
  • 我刚刚使用“线程”菜单进行了调试,当我设置断点并使用 F10 检查下一条语句时,代码似乎工作正常.. 但是当我删除断点并正常运行代码时,它不会工作。你能想出一个原因吗? @PeterDuniho 顺便感谢您的帮助
  • 您之前的评论帮我解决了!我无法在同一个套接字上为每个客户端启动一个线程,所以我将通信保持在一个线程中,并制作了一组 IPEndPoint 来跟踪我的客户端。感谢您的帮助@PeterDuniho
  • 太棒了...很高兴听到您整理了所有内容。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-17
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-21
相关资源
最近更新 更多