[Resolvido]GMS Stack overflow...

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

Resolvido [Resolvido]GMS Stack overflow...

Mensagem por Witen em Dom 22 Jun 2014, 12:35

Quando executo este código:
Código:
///SendClient(type)
switch(argument0){
    case 'self':
        network_send_packet(_Socket,_Buffer,buffer_tell(_Buffer));
        CountSend()
    break

    case 'all':
        for(_Pos = 0;_Pos <= ds_list_size(List_Id);_Pos++){
        network_send_packet(ds_list_find_value(List_Socket,_Pos),_Buffer,buffer_tell(_Buffer));
        CountSend();}
    break;

    case 'same room':
    var _Pos = ds_list_find_index(List_Socket,_Socket);Cur_Room = ds_list_find_value(List_Cur_Room,_Pos)
    for(_Pos = 0;_Pos <= ds_list_size(List_Id);_Pos++){
    if ds_list_find_value(List_Cur_Room,_Pos) == Cur_Room
        network_send_packet(ds_list_find_value(List_Socket,_Pos),_Buffer,buffer_tell(_Buffer));
        CountSend()}
    break;
}
Aparece uma janela com o nome Stack overflow... e o nome do script gml_Scrpt_SendClient dentro da janela, pesquisei e pelo que vi, é uma mensagem que abre quando algum código causa um loop infinito travando o processamento e ocupando muita memoria, no caso acho que o GMS avisa antes de acontecer mas isso inutiliza o meu script. Alguém pode me ajudar? Happy"

descobrir que esta é a função que esta causando o problema, mas ainda não sei como resolver:
Código:
network_send_packet(_Socket,_Buffer,buffer_tell(_Buffer));


Última edição por Witen em Ter 01 Jul 2014, 11:05, editado 2 vez(es)

Witen

Ranking : Sem avaliações
Número de Mensagens : 515
Idade : 17
Data de inscrição : 23/05/2012
Reputação : 36
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

http://www.wibix.webs.com

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido]GMS Stack overflow...

Mensagem por Kabeção em Dom 22 Jun 2014, 13:12

O que esse CountSend() faz?

Não é exatamente um loop, stack overflow no GMS normalmente é quando você esta usando muitas chamadas recursivas, ou seja, chamando o próprio script dentro do mesmo:

Código:
/// script_recursivo()
v++;

if v < 28 script_recursivo();

O GMS tem um limite para isso.
O script acima funcionaria normalmente mas:

Código:
/// script_recursivo()
v++;

if v < 100000 script_recursivo();

Com certeza retornaria um erro de stack overflow.

Kabeção

Ranking : Sem avaliações
Número de Mensagens : 2314
Data de inscrição : 08/06/2008
Reputação : 100
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 3
   : 0
   : 1

http://blackcapapps.blogspot.com.br/

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido]GMS Stack overflow...

Mensagem por Witen em Qua 25 Jun 2014, 12:55

@Kabeção O script CountSend é só para atualizar o trafego.
Código:
global.Up_Sec  += buffer_tell(_Buffer);
global.Up_Total += buffer_tell(_Buffer);

Witen

Ranking : Sem avaliações
Número de Mensagens : 515
Idade : 17
Data de inscrição : 23/05/2012
Reputação : 36
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

http://www.wibix.webs.com

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido]GMS Stack overflow...

Mensagem por Kabeção em Qua 25 Jun 2014, 13:20

Esse erro é para qualquer coisa que esta expandindo ao limite a memoria que pode ser usada pelo script.
Você deve estar enviando muitos pacotes.

Kabeção

Ranking : Sem avaliações
Número de Mensagens : 2314
Data de inscrição : 08/06/2008
Reputação : 100
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 3
   : 0
   : 1

http://blackcapapps.blogspot.com.br/

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido]GMS Stack overflow...

Mensagem por Witen em Qua 25 Jun 2014, 15:32

Notei que quando o serve recebe uma mensagem network_type_connect(tipo 1), de conexão, se o server manda um pacote usando o _Socket do client envia sem nenhum problema, agora se for uma conexão network_type_data(tipo 3), e o server tenta enviar um pacote, da esse problema.
Ai eu imaginei que como o server é o client são locais(esta no mesmo computador) o próprio server estava recebendo o pacote enviado e enviando outro e assim por diante criando um loop infinito, mas isso eu eliminei, é pouco provável(Apesar que, creio eu ser possível, pois quando o client se conecta com o server as portas são especificadas, mas o contrario não acontece )...
O código dentro do evento Networking
Código:
//Aqui é onde vão chegar as mensagens dos clientes
/*As mensagens chegam num ds_map conhecido como AsyncLoad, vamos pegar o conteúdo dessa estrutura e jogar nas
nossas variáveis. Assim podemos ler e tratar tudo que chega dos clientes.*/
//-----------------------------Informacoes do pacote -------------------------------------//
_Type      = ds_map_find_value(async_load,"type"); // o Tipo do pacote (Pedido de conexão, Pedido de desconexão ou dados)
_Id        = ds_map_find_value(async_load,"id"); // ID de quem enviou dado (caso seja um pacote de dados)
_Ip        = ds_map_find_value(async_load,"ip"); //IP de quem enviou o pacote
_Socket    = ds_map_find_value(async_load,"socket"); //ID de quem enviou o pedido de conexão ou desconexão
Read_Buffer = ds_map_find_value(async_load,"buffer");//Se existe buffer de dados
_Size      = ds_map_find_value(async_load,"size");//Qual o tamanho do buffer de dados
//-------------------------atualizando o trafego de dados---------------------------------//
global.Down_Sec  += _Size
global.Down_Total += _Size
//----------------------------------------------------------------------------------------//
if _Type == network_type_data{
switch(buffer_read(Read_Buffer,buffer_u8)){
    case MSG_ACCOUNT_CREATE:MsgAccountCreate()break;
    case MSG_LOGIN:MsgLogin()break;
    case MSG_ENTER:MsgEnter()break;
    case MSG_REQUEST_POS:MsgRequestPos()break;
    case MSG_SEND_COORDINATES:MsgSendCoordinates()break;
    case MSG_LEAVE:MsgLeave()break;
    case MSG_NEW_CONTACT:MsgNewContact()break;
    case MSG_WARP:MsgWarp()break;
    case MSG_BAN:MsgBan()break;
    case MSG_CHAT:MsgChat()break;
    case MSG_NAVIGATOR:break; 
    case MSG_MB:break;
    case MSG_NEW_ROOM:MsgCreateRoom()break;
    case MSG_AT_ROOMS :break;
    case MSG_NEW_EVENT :break;
    case MSG_ADD_LISTEVENT:break
}}
Script MsgLogin()
Código:
var Acc_Pth,_Name,_Pass,_List,_File;
_Name  = buffer_read(Read_Buffer,buffer_string); 
_Pass  = buffer_read(Read_Buffer,buffer_string);

Acc_Pth = working_directory+'\Accounts\'+_Name+'.ini'
if file_exists(Acc_Pth){
_List  = ds_map_create();
_File  = file_text_open_read(Acc_Pth);
_List  = ds_map_read(_List,file_text_read_string(_File));
file_text_close(_File);}

if (!file_exists(Acc_Pth)){
    BufferRestart()
        buffer_write(_Buffer,buffer_u8,MSG_LOGIN_USER_NO_EXIST)
    SendClient()
exit}
if (file_exists(working_directory+'\Accounts\Ban\'+_Name+'.ini')){
    BufferRestart()
        buffer_write(_Buffer,buffer_u8,MSG_LOGIN_USER_BANNED)
    SendClient()
exit}
if (ds_list_find_index(List_Name,_Name) != -1){
    BufferRestart()
        buffer_write(_Buffer,buffer_u8,MSG_LOGIN_ACCOUNT_IN_USE)
    SendClient()
exit}
if (_Pass != ds_map_find_value(_List,'Pass')){
    BufferRestart()
        buffer_write(_Buffer,buffer_u8,MSG_LOGIN_INVALID_PASSWORD)
    SendClient()
exit}

List_Socket = ds_list_add(List_Socket    ,_Socket);
List_Ip    = ds_list_add(List_Ip        ,_Ip);
List_Name  = ds_list_add(List_Name      ,ds_map_find_value(_List,'Name' ));
List_Pass  = ds_list_add(List_Pass      ,ds_map_find_value(_List,'Pass' ));
List_Email  = ds_list_add(List_Email    ,ds_map_find_value(_List,'Email'));
List_Sexo  = ds_list_add(List_Sexo      ,ds_map_find_value(_List,'Sexo' ));
List_Data  = ds_list_add(List_Data      ,ds_map_find_value(_List,'Data' ));
List_Old_Room = ds_list_add(List_Old_Room,'');
List_Cur_Room = ds_list_add(List_Cur_Room,'');
ds_map_destroy(_List)
    BufferRestart()
        buffer_write(_Buffer,buffer_u8,MSG_LOGIN_SUCCESS)
    SendClient()
    global.Clientes_Online++;

Witen

Ranking : Sem avaliações
Número de Mensagens : 515
Idade : 17
Data de inscrição : 23/05/2012
Reputação : 36
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

http://www.wibix.webs.com

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido]GMS Stack overflow...

Mensagem por fredcobain em Seg 30 Jun 2014, 18:51

Notei que quando o serve recebe uma mensagem network_type_connect(tipo 1), de conexão, se o server manda um pacote usando o _Socket do client envia sem nenhum problema, agora se for uma conexão network_type_data(tipo 3), e o server tenta enviar um pacote, da esse problema.

Sim, vai dar esse problema mesmo, porque quando é um evento do tipo 3 (data), o pacote fica em outra variável.

Imagino que vc tenha lido o meu tutorial de networking, mas se vc ler com bastante atenção eu explico isso nessa linha:

Tutorial de Networking do Fredcobain escreveu:Sempre que um cliente (já conectado) manda alguma mensagem para o server, o mapa async_load novamente é carregado com informações.
A informação que vc precisa (ID do SOCKET) estará na variável ID desse mapa. Então vc sabe quem mandou a mensagem.

Penso que aí está a chave pra resolver seu problema

fredcobain

Ranking : Sem avaliações
Número de Mensagens : 691
Idade : 35
Data de inscrição : 14/04/2011
Reputação : 162
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido]GMS Stack overflow...

Mensagem por Witen em Ter 01 Jul 2014, 11:04

Nossa cara era isso mesmo, UMA SEMANA QUEBRANDO A CABEÇA!!! pra isso kkkkkkkk
Não sei se choro ou dou risada u.u" muito obrigado mesmo. Mas é serio da um editezinho no seu tutorial e especifica mais essa parte, obrigado Happy"

Witen

Ranking : Sem avaliações
Número de Mensagens : 515
Idade : 17
Data de inscrição : 23/05/2012
Reputação : 36
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

http://www.wibix.webs.com

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido]GMS Stack overflow...

Mensagem por Conteúdo patrocinado Hoje à(s) 23:56


Conteúdo patrocinado


Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum