【问题标题】:UDP Server, Output doubles after each LoopUDP 服务器,每次循环后输出加倍
【发布时间】:2017-01-06 10:52:23
【问题描述】:

我有一个运行良好的 UDP 服务器/客户端程序。

我将收到的消息从一个客户端发送回所有连接的客户端,但每个循环后输出加倍。 我想我必须用客户端重置 ListArray,但是只有第一条消息会被发送。

有人知道吗?谢谢!

UDP 服务器

    //Listening on Port 12222
    int servPort = 12222;

    UdpClient client = null;

    //Create a new ListArray for the connected Clients
    ArrayList IPArray = new ArrayList();

    try
    {
        //Create an instance of UdpClient
        client = new UdpClient(servPort);
    }
    catch (SocketException se)
    {
        Console.WriteLine(se.ErrorCode + ": " + se.Message);
        Environment.Exit(se.ErrorCode);
    }

    //Create an new IPEndPoint
    IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, 0);


    //Endless loop
    for (; ; )
    { 
        try
        {
            //Receive a byte array with contents
            byte[] byteBuffer = client.Receive(ref remoteIPEndPoint);

            //Message from Client
            string returnData = Encoding.ASCII.GetString(byteBuffer);

            //Add connected Client IPs to ListArray
            IPArray.Add(remoteIPEndPoint);

            //Send the received Message back to all Clients in the ArrayList
            for (int i = 0; i < IPArray.Count; i++)
            {
                Console.WriteLine("Handling client at " + IPArray[i] + " - " + returnData + " arraylist.Length " + IPArray.Count + "\n");

                Byte[] sendBytes = Encoding.ASCII.GetBytes("Clients Send " + returnData + "\n");
                client.Send(sendBytes, sendBytes.Length, (IPEndPoint)IPArray[i]);
            }

            Console.WriteLine("echoed {0} bytes.", byteBuffer.Length);
        }
        catch (SocketException se)
        {
            Console.WriteLine(se.ErrorCode + ": " + se.Message);
        }
    }
}

UDP 客户端

//Server name or IP address
static String server = "127.0.0.1";     

//Port
static int servPort = 12222;

//Convert String to an array of bytes
static string message = "ICH";

static void Main(string[] args)
{
    SendReceive();
}

static byte[] sendPacket = Encoding.ASCII.GetBytes(message);

//Create an instance of UdpClient
static UdpClient client = new UdpClient();

static void SendReceive()
{
    try
    {
        //Send the string to the specified Server and Port
        client.Send(sendPacket, sendPacket.Length, server, servPort);

        Console.WriteLine("Sent {0} bytes to the server...", sendPacket.Length);

        IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, 0);

        //Attempt Message reply receive
        byte[] rcvPacket = client.Receive(ref remoteIPEndPoint);

        Console.WriteLine("Received {0} bytes from {1}: {2}",
                          rcvPacket.Length, remoteIPEndPoint,
                          Encoding.ASCII.GetString(rcvPacket, 0, rcvPacket.Length));
    }
    catch (SocketException se)
    {
        Console.WriteLine(se.ErrorCode + ": " + se.Message);
    }

    //Console.ReadKey();

    //client.Close();
    Thread.Sleep(500);

    //Endless Loop
    SendReceive();
}

UDP 服务器:

【问题讨论】:

  • 这是预期的,因为代码正在执行cmd上显示的内容!它将继续接收每个客户端响应的字节。因此,随着列表中项目数量的增加,服务器会多次回显 Handling client... 消息。你的问题不清楚你想要什么?
  • 抱歉我的英语不好。带有 iP 地址的数组随着来自客户端的每条消息而增长,但我只想要客户端发送的最后一条消息。

标签: sockets tcp server network-programming udp


【解决方案1】:

带有 iP 地址的数组随着来自 客户,但我只想要客户发送的最后一条消息。

如果这是要求,则不需要循环。此外,在没有arraylist 的帮助下,您可以使用remoteIPEndPoint 本身显示各个客户端的详细信息。这是做你想做的事的更简洁的方式。

从 UDP 服务器中删除以下行:

...
       //Send the received Message back to all Clients in the ArrayList
        for (int i = 0; i < IPArray.Count; i++)
        {
            Console.WriteLine("Handling client at " + IPArray[i] + " - " + returnData + " arraylist.Length " + IPArray.Count + "\n");

            Byte[] sendBytes = Encoding.ASCII.GetBytes("Clients Send " + returnData + "\n");
            client.Send(sendBytes, sendBytes.Length, (IPEndPoint)IPArray[i]);
        }
...

您需要显示发送消息的客户端的 IP 地址和端口号。相反,添加以下行:

//1. Now, you can show the count, but, you can get the indiviudal client detail  
//using the remoteIPEndPoint, there is no need of iterating through the array.
Console.WriteLine("This message was sent from " + remoteIPEndPoint.Address.ToString() +
                             " on their port number " +
                             remoteIPEndPoint.Port.ToString() + " - " + returnData + "\n");

//2. Then send the data back to the individual client without using ArrayList, 
// by passing the client's IPEndPoint in the Send() method.
Byte[] sendBytes = Encoding.ASCII.GetBytes("Clients Send " + returnData + "\n");
client.Send(sendBytes, sendBytes.Length, remoteIPEndPoint);

它的作用是显示将消息发送到服务器的客户端的 IP 地址和端口号。\


另外,目前的方式对于网络/套接字编程来说并不是更好的方式。您应该始终使用单独的线程(使用 ConnectionQueue 将它们限制在池中)来接收每个客户端的消息。使用 ConnectionQueue 来维护线程的顺序(可以为每个新的客户端请求重用)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-30
    相关资源
    最近更新 更多