Пакеты не читаются TCP - PullRequest
       2

Пакеты не читаются TCP

0 голосов
/ 24 января 2019

У меня проблема с сокетами. Я терял пакеты на стороне клиента, у меня есть определенный метод на сервере, который потенциально мог бы посылать 3 пакета действительно быстро большому количеству клиентов.После отладки я обнаружил, что проблема заключалась не в самом сервере, а в клиенте, он не может читать, я уверен, он недостаточно быстро вызывает WaitForData, поэтому он действительно никогда не знает, что получает пакет.В настоящее время у меня есть решение, но оно не самое лучшее, так как я искажаю сервер с помощью ожидающего Task.Delay.Любые идеи о том, как улучшить синхронизацию метода RecibirPaquetes (это на самом деле обрабатывает пакеты и запускает событие для фронт-приложения)?или какие-либо другие идеи о том, как справиться с этой конкретной проблемой?Я оставляю эти 2 метода здесь

    public void WaitForData()
    {
        try
        {
            if (wdCallBack == null)
            {
                wdCallBack = new AsyncCallback(RecibirPaquetes);
            }
            SocketPacket theSocPkt = new SocketPacket();
            theSocPkt.thisSocket = _cliente;
            m_result = _cliente.BeginReceive(theSocPkt.dataBuffer,
                                                    0, theSocPkt.dataBuffer.Length,
                                                    SocketFlags.None,
                                                    wdCallBack,
                                                    theSocPkt);
        }
        catch (SocketException ex)
        {
            //this basically resets the client if the waitfordata fails
            System.Diagnostics.Process.Start("mataPrograma.bat");
        }
    }


 private void RecibirPaquetes(IAsyncResult ar)
    {
        try
        {
            SocketPacket server = (SocketPacket)ar.AsyncState;

            int cant_recibido;
            try
            {
                cant_recibido = server.thisSocket.EndReceive(ar);
                Log("cant_recibido OK", LogSeverity.NORMAL);
            }
            catch (Exception ex)
            {
                Log($"cant_recibido Fallo: {ex.Message}", LogSeverity.ERROR);
                server.thisSocket.Close();

                server.thisSocket = null;

                if (ConexionCerrada != null)
                {
                    ConexionCerrada();
                }

                return;
            }

            if (cant_recibido == 0)
            {
                Log($"cantidad recibida es nula se cierra conexion", LogSeverity.NORMAL);

                server.thisSocket.Close();

                server.thisSocket = null;

                if (ConexionCerrada != null)
                {
                    ConexionCerrada();
                }

                return;
            }

            server.thisSocket.NoDelay = true;

            byte[] paqueteRecibido = new byte[cant_recibido];

            Array.Copy(server.dataBuffer, paqueteRecibido, cant_recibido);

            var paquete = paqueteRecibido.Deserializar();

            if (MensajeRecibido != null)
            {
                MensajeRecibido(paquete as PaqueteServidor);
                Log($"RecibirPaquete: Comando = {((PaqueteServidor)paquete).Comando.ToString()} Contenido = {paquete.Datos}", LogSeverity.NORMAL);
            }
            else
            {
                Log($"FALLO! RecibirPaquete: Comando = {((PaqueteServidor)paquete).Comando.ToString()} Contenido = {paquete.Datos}", LogSeverity.ERROR);
            }
            if (PaqueteComando(paquete as PaqueteServidor) != Comando_Servidor.EXPULSAR && (PaqueteComando(paquete as PaqueteServidor) != Comando_Servidor.CAMBIAR_SESION || soyMonitor))
            {
                WaitForData();
            }

        }
        catch (Exception ex)
        {
            Log($"RecibirPaquete: {ex.Message}", LogSeverity.ERROR);
            if (MensajeError != null)
            {
                MensajeError(ex);
            }
            WaitForData();
        }
    }

РЕДАКТИРОВАТЬ: добавление, как сервер отправляет пакеты

 public void EnviarPaquete(PaqueteServidor paquete, Socket cliente, ENVIAR_A tipo, List<ClienteConectado> custom = null)
    {
        try
        {
            semaphorePaquetes.Wait();

            var conectados = this.clientesConectados.ToList(); //probar esto

            paqueteId += 1;
            paquete.Serial = paqueteId;

            switch (tipo)
            {

                case ENVIAR_A.TODOS:

                    foreach (var item in conectados)
                    {
                        if (item._socket.Connected)
                        {
                            item._socket.Send(paquete.Serializar(), 0, paquete.Serializar().Length, SocketFlags.None);

                            this.cantPaquetesEnviados += 1;
                            this.bytesEnviados += Convert.ToUInt64(paquete.Serializar().Length);
                        }
                    }

                    break;

                case ENVIAR_A.TODOS_MENOS_TARGET:

                    foreach (var item in conectados.Where(w => w._socket.RemoteEndPoint.ToString() != cliente.RemoteEndPoint.ToString()))
                    {
                        if (item._socket.Connected)
                        {
                            item._socket.Send(paquete.Serializar(), 0, paquete.Serializar().Length, SocketFlags.None);

                            this.cantPaquetesEnviados += 1;
                            this.bytesEnviados += Convert.ToUInt64(paquete.Serializar().Length);
                        }
                    }

                    break;

                case ENVIAR_A.SOLO_LEGISLADORES:

                    foreach (var item in conectados.Where(w => w.Actor.Labor.id_cargo_tipo == 0))
                    {
                        if (item._socket.Connected)
                        {
                            item._socket.Send(paquete.Serializar(), 0, paquete.Serializar().Length, SocketFlags.None);

                            this.cantPaquetesEnviados += 1;
                            this.bytesEnviados += Convert.ToUInt64(paquete.Serializar().Length);
                        }
                    }

                    break;

                case ENVIAR_A.ESTRADO:

                    foreach (var item in conectados.Where(w => w.Estrado == true))
                    {
                        if (item._socket.Connected)
                        {
                            item._socket.Send(paquete.Serializar(), 0, paquete.Serializar().Length, SocketFlags.None);

                            this.cantPaquetesEnviados += 1;
                            this.bytesEnviados += Convert.ToUInt64(paquete.Serializar().Length);
                        }
                    }

                    break;

                case ENVIAR_A.NO_ESTRADO:

                    foreach (var item in conectados.Where(w => w.Estrado == false))
                    {
                        if (item._socket.Connected)
                        {
                            item._socket.Send(paquete.Serializar(), 0, paquete.Serializar().Length, SocketFlags.None);

                            this.cantPaquetesEnviados += 1;
                            this.bytesEnviados += Convert.ToUInt64(paquete.Serializar().Length);
                        }
                    }

                    break;

                case ENVIAR_A.TARGET:


                    if (cliente.Connected)
                    {
                        cliente.Send(paquete.Serializar(), 0, paquete.Serializar().Length, SocketFlags.None);

                        this.cantPaquetesEnviados += 1;
                        this.bytesEnviados += Convert.ToUInt64(paquete.Serializar().Length);
                    }

                    break;

                case ENVIAR_A.CUSTOM:

                    foreach (var item in custom)
                    {
                        if (item._socket.Connected)
                        {
                            item._socket.Send(paquete.Serializar(), 0, paquete.Serializar().Length, SocketFlags.None);

                            this.cantPaquetesEnviados += 1;
                            this.bytesEnviados += Convert.ToUInt64(paquete.Serializar().Length);
                        }
                    }

                    break;
            }
        }
        catch (Exception ex)
        {
            aLogear.Enqueue(new Log("EnviarPaquete: " + ex.Message, TipoLog.ERROR, ClaseLog.SERVER));
        }
        finally
        {
            semaphorePaquetes.Release();
        }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...