Avatar billede bildsoe Nybegynder
12. september 2011 - 14:59 Der er 2 kommentarer og
1 løsning

Kommunikation mellem UDP-klient og UDP-server

Jeg arbejder på at lave en UDP-klient og UDP-server der skal bruges til at sende oplysninger mellem klienter og en central server og fra serveren ud til en maskine.

Jeg får følgende fejlmeddelelse:

A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself.

Før jeg sender den pakke der fører til fejlen prøver jeg at tjekke på, hvad den fylder og jeg får svaret: 17 og den buffer jeg bruger i begge ender er 1024 bytes altså burde der ikke opstå nogen problemer. Er der nogen der har erfaring med UPD og ved, hvad der kan fremkalde denne fejl? Koden er forholdsvis lang så jeg kan lægge bidder af den ud, eller sende hele koden på efterspørgsel.
Avatar billede arne_v Ekspert
13. september 2011 - 01:53 #1
Vi skal ok se lidt kode.

:-)

Foelgende virker fint her:

            UdpClient srv = new UdpClient(12345);
            IPEndPoint snd = new IPEndPoint(IPAddress.Any, 0);
            byte[] b = srv.Receive(ref snd);
            Console.WriteLine("Received {0} bytes from {1} port {2}", b.Length, snd.Address.ToString(), snd.Port);
            srv.Close();

og

            UdpClient cli = new UdpClient(12346);
            byte[] b = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
            IPAddress addr = Dns.GetHostAddresses("localhost").First(a => a.AddressFamily == AddressFamily.InterNetwork);
            Console.WriteLine(addr);
            cli.Send(b, b.Length, new IPEndPoint(addr, 12345));
            cli.Close();
Avatar billede bildsoe Nybegynder
13. september 2011 - 09:15 #2
Det underlige er at jeg først sender et connect request, bare et 1-tal til serveren, så sender den ok tilbage, så ber klienten om data, men når serveren så sender det tilbage får jeg fejl-meddelelsen.

Jeg sender/modtager beskeder asynkront, så kan prøve at vises koden jeg åbner socket med, og så den delegate som håndterer når den modtager data.

Server[b/]
enum Command
    {
        Connect = 1,    //Log into the server
        Disconnect,    //Logout of the server
        Job,            //Send the data for a specific job
        List,          //Send a list of all jobs
        Null            //No command
    }
   
    class UdpServer
    {

        public RichTextBox _display { get; set; }

        //The ClientInfo structure holds the required information about every
        //client connected to the server
        struct ClientInfo
        {
            public EndPoint endpoint;  //Socket of the client
            public string strName;      //Name by which the user logged in, this is used to decide what action to take
        }

        //The collection of all clients connected (an array of type ClientInfo)
        ArrayList clientList;

        ClientInfo machineClient = new ClientInfo();
       
        //The main socket on which the server listens to the clients
        Socket serverSocket;

        byte[] byteData = new byte[1024];

        public UdpServer()
        {
            clientList = new ArrayList();
        }

        public void connect()
        {
            try
            {
                _display.Text += "Server started...\n";
               
                //We are using UDP sockets
                serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

                //Assign the any IP of the machine and listen on port number 1000
                IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 1000);

                //Bind this address to the server
                serverSocket.Bind(ipEndPoint);

                IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
                //The epSender identifies the incoming clients
                EndPoint epSender = (EndPoint)ipeSender;

                //PING TEST
                sendTest();

                //Start receiving data
                serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length,
                    SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);

               

            }
            catch (Exception ex)
            {
                MessageBox.Show("Connect:" + ex.Message, "ElementServer",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            } 
        }

        private void OnReceive(IAsyncResult ar)
        {
            try
            {
                IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
                EndPoint epSender = (EndPoint)ipeSender;

                serverSocket.EndReceiveFrom(ar, ref epSender);

                _display.Text += "data:"+Encoding.UTF8.GetString(byteData)+"\n";

                //Transform the array of bytes received from the user into an
                //intelligent form of object Data

                Data msgReceived = new Data(byteData);

                byte[] message;

                switch (msgReceived.cmdCommand)
                {
                    case Command.Connect:

                        //When a user connects to the server then we add her to our
                        //list of clients
                       
                        ClientInfo clientInfo = new ClientInfo();
                        clientInfo.endpoint = epSender;
                        clientInfo.strName = msgReceived.strClientType;

                        //If client-type as expressed in strName is machine, then acknowledge that login went well.
                        if (msgReceived.strClientType == "machine")
                        {
                           
                            machineClient = clientInfo;

                            _display.Text += "Machine is connected from ip:" + epSender.ToString() + "\n";

                            message = Encoding.UTF8.GetBytes("1");

                            //Send the message to the machine
                            serverSocket.BeginSendTo(message, 0, message.Length, SocketFlags.None, epSender,
                                new AsyncCallback(OnSend), epSender);

                        }
                        if (msgReceived.strClientType == "user")
                        {
                            clientList.Add(clientInfo);
                            _display.Text += "User connected from ip: " + epSender.ToString() + "\n";

                            message = Encoding.UTF8.GetBytes("1:user:blabla:");

                            //Send the message to the machine
                            serverSocket.BeginSendTo(message, 0, message.Length, SocketFlags.None, epSender,
                                new AsyncCallback(OnSend), epSender);

                        }

                        break;

                    case Command.Disconnect:

                        //When a user wants to disconnect from the server then we search for her
                        //in the list of clients and close the corresponding connection


                        if (msgReceived.strClientType == "user")
                        {
                            foreach (ClientInfo client in clientList)
                            {
                                if (client.endpoint.Equals(epSender))
                                {
                                    clientList.Remove(client);
                                    break;
                                }
                            }

                            _display.Text += "User logged out from ip: " + epSender.ToString() + "\n";

                        }

                        break;

                    case Command.Job:

                        if (msgReceived.strClientType == "user")
                        {
                            BLL bll = new BLL();

                            bll.insertJob(msgReceived.strMessage, 1, 1);

                            _display.Text += msgReceived.strMessage + "\n";
                        }
                        else if (msgReceived.strClientType == "machine")
                        {
                            _display.Text += "Machine requests element data from... \n";
                            _display.Text += "Machine wants element:" + msgReceived.strMessage + "\n";
                         

                            _display.Text += "Element data from has been sent... \n";
                        }

                        break;

                    case Command.List:

                        if (msgReceived.strClientType == "machine")
                        {

                            _display.Text += "Machine requests a list of jobs\n";
                            BLL bll = new BLL();

                            string str = "4-" + bll.getTopTenJobs();

                            message = Encoding.UTF8.GetBytes(str);

                            _display.Text += "TopTenJobs:" + str + "\n is returned...\n";

                            //Send the message to the machine
                            serverSocket.BeginSendTo(message, 0, message.Length, SocketFlags.None, epSender,
                                new AsyncCallback(OnSend), epSender);
 

                        }else if(msgReceived.strClientType == "user")
                        {
                            _display.Text += "User requests a list of jobs\n";

                            //BLL bll = new BLL();

                            byte[] newByte = new byte[1024];

                            newByte = Encoding.UTF8.GetBytes("4:user:Yeeeeeees:");

                            _display.Text += "Message size:" + newByte.Length;

                            //Send the message to the machine
                            serverSocket.BeginSendTo(newByte, 0, newByte.Length, SocketFlags.None, epSender,
                                new AsyncCallback(OnSend), epSender);
                        }

                        break;

                    case Command.Null:

                        _display.Text += "Ping received\n";

                        break;

                   
                }

                //Start listening for messages
                serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epSender,
                    new AsyncCallback(OnReceive), epSender);

                //Resetting byteData
                Array.Clear(byteData, 0, byteData.Length);

            }
            catch (Exception ex)
            {
                MessageBox.Show("OnReceive:" + ex.Message, "ElementServer", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void OnSend(IAsyncResult ar)
        {
            try
            {
                serverSocket.EndSend(ar);
            }
            catch (Exception ex)
            {
                MessageBox.Show("OnSend:" + ex.Message, "ElemenServer", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void sendTest()
        {
            //Send test message
            byte[] tada = Encoding.UTF8.GetBytes("5");

            IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("192.168.1.177"), 8888);
            //The epSender identifies the incoming clients
            EndPoint ep = (EndPoint)ipe;

            serverSocket.BeginSendTo(tada, 0, tada.Length, SocketFlags.None, ep, new AsyncCallback(OnSend), ep);
        }

    }


[b]Client

enum Command
    {
        Connect = 1,      //Log into the server
        Disconnect,    //Logout of the server
        Job,        //Send the data for a specific job
        List,      //Send a list of all jobs
        Null
    }

    class udpClient
    {
        public IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
        string name = "user";

        public Socket clientSocket;
        public EndPoint epServer;
       
        byte[] byteData = new byte[1024];

        public bool connect()
        {

            try
            {
                //Using UDP sockets
                clientSocket = new Socket(AddressFamily.InterNetwork,
                    SocketType.Dgram, ProtocolType.Udp);

                //Server is listening on port 1000
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 1000);

                epServer = (EndPoint)ipEndPoint;

                Data msgToSend = new Data();
                msgToSend.cmdCommand = Command.Connect;
                msgToSend.strMessage = null;
                msgToSend.strClientType = name;

                byteData = msgToSend.ToByte();

                //Login to the server
                clientSocket.BeginSendTo(byteData, 0, byteData.Length,
                    SocketFlags.None, epServer, new AsyncCallback(OnSend), null);

                return true;
            }
            catch (ObjectDisposedException ex)
            {
                MessageBox.Show("CONNECT" + ex.Message + ":" + ex.ObjectName + ":" + ex.StackTrace, "UdpClient",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }

        }

        public void sendMessage(jobInfo message)
        {
            try
            {
                //Fill the info for the message to be send
                Data msgToSend = new Data();

                msgToSend.strClientType = name;
                msgToSend.strMessage = message.jobCase.ToString()+"%"+message.jobID.ToString()+"%"+message.jobName+"%"+message.jobData+"%";
                msgToSend.cmdCommand = Command.Job;

                byte[] byteData = msgToSend.ToByte();

                //Send it to the server
                clientSocket.BeginSendTo(byteData, 0, byteData.Length, SocketFlags.None, epServer, new AsyncCallback(OnSend), null);

            }
            catch (Exception)
            {
                MessageBox.Show("Unable to send message to the server.", "UDPServer: " + name, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }


        public void requestData()
        {
            //Start listening for messages
            clientSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epServer,
                new AsyncCallback(OnReceive), epServer);
        }
     
        public void closeConnection()
        {
            try
            {
                //Send a message to logout of the server
                Data msgToSend = new Data();
                msgToSend.cmdCommand = Command.Disconnect;
                msgToSend.strClientType = name;
                msgToSend.strMessage = null;

                byte[] b = msgToSend.ToByte();
                clientSocket.BeginSendTo(b, 0, b.Length, SocketFlags.None, epServer, new AsyncCallback(OnSend), null);
               
            }
            catch (Exception ex)
            {
                MessageBox.Show("Close:" + ex.Message+":"+ex.Source+"", "UDPClient: " + name, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void OnSend(IAsyncResult ar)
        {
            try
            {
                if (clientSocket.Connected)
                    clientSocket.EndSend(ar);
            }
            catch (Exception ex)
            {
                MessageBox.Show("OnSend:" + ex.Message + ":" + ex.Source + "", "UdpClient", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void OnReceive(IAsyncResult ar)
        {
            try
            {
                clientSocket.EndReceive(ar);

                MessageBox.Show(Encoding.UTF8.GetString(byteData));

                //Transform the array of bytes received from the user into an
                //intelligent form of object Data

                Data msgReceived = new Data(byteData);

                switch (msgReceived.cmdCommand)
                {

                    case Command.Connect:

                        MessageBox.Show("the right place");

                        byte[] message = Encoding.UTF8.GetBytes("4:user:blabla:");

                        clientSocket.BeginSendTo(message, 0, message.Length, SocketFlags.None, epServer, new AsyncCallback(OnSend), null);

                        break;

                    case Command.Disconnect:


                        break;
                   
                    case Command.List:
                        MessageBox.Show("Incoming list!!!!!!");

                        break;

                    case Command.Null:

                        break;


                }
               
               
                //Start listening for messages
                clientSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epServer,
                    new AsyncCallback(OnReceive), epServer);
               
                //Resetting byteData
                Array.Clear(byteData, 0, byteData.Length);

            }
            catch (Exception ex)
            {
                MessageBox.Show("OnReceive:" + ex.Message, "UdpClient", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
       

    }

    //The data structure by which the server and the client interact with
    //each other
    class Data
    {
        //Default constructor
        public Data()
        {
            this.cmdCommand = Command.Null;
            this.strMessage = null;
            this.strClientType = null;
        }

        //Converts the bytes into an object of type Data
        public Data(byte[] data)
        {

            string allReceived = Encoding.UTF8.GetString(data);

            string[] parts = allReceived.Split(':');

            //The first part of the message is the command
            this.cmdCommand = (Command)int.Parse(parts[0]);

            //The next part of the message is the sender type, we have machine and user types
            this.strClientType = parts[1];

            //The final part of the message is the actual message
            this.strMessage = parts[2];
        }

        //Converts the Data structure into an array of bytes
        public byte[] ToByte()
        {

            string str = ((int)cmdCommand).ToString();

            List<byte> result = new List<byte>();

            result.AddRange(Encoding.UTF8.GetBytes(str));

            result.AddRange(Encoding.UTF8.GetBytes(":"));

            result.AddRange(Encoding.UTF8.GetBytes(strClientType));

            result.AddRange(Encoding.UTF8.GetBytes(":"));

            if(strMessage!=null)
                result.AddRange(Encoding.UTF8.GetBytes(strMessage));

            result.AddRange(Encoding.UTF8.GetBytes(":"));

            return result.ToArray();
        }

        public string strClientType;   
        public string strMessage; 
        public Command cmdCommand; 
    }
Avatar billede bildsoe Nybegynder
11. november 2011 - 08:42 #3
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester