数据包未读取TCP

时间:2019-01-24 13:30:07

标签: c# tcp

如果套接字有问题,我在客户端丢失了数据包,我在服务器中有某种​​方法可以有效地向许多客户端快速发送3个数据包。调试之后,我发现问题不是服务器本身,而是客户端,他无法读取,我敢打赌,它没有足够快地调用WaitForData,因此他真的不知道自己正在接收数据包。我目前有一个解决方案,但这不是最好的解决方案,因为使用await 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();
        }

    }

0 个答案:

没有答案