Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

seuqram

[Resolvido] SDL_net server-client

Mensagens Recomendadas

seuqram

Boa Tarde. Há poucos dias resolvi começar a fazer um servidor-client a utilizar o SDL_net.

Tenho que ter um protocolo rápido (UDP), onde pode haver perdas, e outro protocolo à parte, que confirme todos os pacotes.

O problema está no segundo. Eu achei muito desafiador fazer esse protocolo através de um sistema baseado no UDP (enviar até receber um feed-back) mas eu estou com receio de que isso possa ficar muito pesado e assim, não o possa utilizar.

O sistema consiste num buffer no client que guarda os pacotes que ainda não foram confirmados dentro de um vetor de string. Eu testei enviar uns 200 pacotes por segundo o que até 30 segundos pareceu tudo normal... Depois, de repente, a conexão é interrompida (o servidor continua ativo). Desligando e tentando ligar o servidor, diz "não foi capaz de se ligar ao port" (o port está no "3114"). Tenho que desligar o servidor e ligá-lo outra vez para volta a dar.

Eu, no codigo, quando envio os pacotes, tenho sempre o canal como -1, ou seja não uso canais individuais para os enviar.

Será que se fazendo uso deles, isto irá ficar mais rápido?

Provavelmente estou a fazer alguma coisa de mal no sistema, será que há modelos de tranformação de UDP->TCP melhores que o buffer/feed-back?

Será que eu devo utilizar os protocolos do SDL_net, TCP e UDP juntos sem andar a inventar coisas?

Ou esta pode ser mesmo uma limitação do meu computador/router?

Cumprimentos.

Editado por pwseo
removida formatação desnecessária

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Depois, de repente, a conexão é interrompida (o servidor continua ativo). Desligando e tentando ligar o servidor, diz "não foi capaz de se ligar ao port" (o port está no "3114"). Tenho que desligar o servidor e ligá-lo outra vez para volta a dar.[/font]

isso tem aspecto normal de um problema grave de código.

é perfeitamente normal quando uma aplicação estoira, a porta fica "pendurada" até o sistema operativo achar que deve libertar a porta novamente.

Provavelmente estou a fazer alguma coisa de mal no sistema, será que há modelos de tranformação de UDP->TCP melhores que o buffer/feed-back?

sim, existe. e como tal, podes ver o que o TCP faz : https://en.wikipedia.org/wiki/Sliding_window_protocol

Será que eu devo utilizar os protocolos do SDL_net, TCP e UDP juntos sem andar a inventar coisas?

depende.

estás a fazer para aprender ou para usar ?

se for para aprender, força. se for para usar, não inventes a roda.

  • Voto 1

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
seuqram
aplicação estoira

O servidor pára provavelmente... pelo excesso de pacotes num pequeno intervalo de tempo?

sim, existe. e como tal, podes ver o que o TCP faz : https://en.wikipedia.org/wiki/Sliding_window_protocol

Eu também tive um ideia parecida. Mas e se nenhum pacote chegasse? Já não podia informar os que faltavam. E mesmo que chegasse um ou dois, o feed back para o client também se podia perder. Ou estará a faltar-me alguma coisa?

estás a fazer para aprender ou para usar ?

se for para aprender, força. se for para usar, não inventes a roda.

Eu estou a tentar fazer um projeto completo. Estou a fazer para aprender, mas ao mesmo tempo para utilizar.

Andei a pesquisar muito, e a maioria da informação que encontro, fazem rivalidade entre o UDP e o TCP, dizem que um é mais rápido que o outro, etc... Dizem que utilizar os protocolos ao mesmo tempo pode meter a ligação mais lenta do que se fosse apenas UDP. E apontam para, quando se precisa de pacotes seguros, fazer uma costumização do UDP.

Na verdade há algumas funcionalidades do TCP que eu não queria o tempo todo, como por exemplo a sequencialização dos pacotes, ou a ligação por stream que eu penso que tire um pouco de velocidade?

Mas eu não sou nenhum expert na coisa, e por isso não sei se conseguia fazer isto tudo como deve ser. O que é que me aconcelha? Utilizar os dois juntos não vai aumentar assim lá muito a latência?

Obrigado pela boa resposta.

Editado por seuqram

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

O servidor pára provavelmente... pelo excesso de pacotes num pequeno intervalo de tempo?

não, a aplicação estoira por outra razão qualquer.

o problema não é pelo número de pacotes que dizes enviar.

Eu também tive um ideia parecida. Mas e se nenhum pacote chegasse? Já não podia informar os que faltavam. E mesmo que chegasse um ou dois, o feed back para o client também se podia perder. Ou estará a faltar-me alguma coisa?

em UDP tens sempre o problema de um pacote não chegar.

é para isso que o TCP serve : fiabilidade de envio de informação.

Eu estou a tentar fazer um projeto completo. Estou a fazer para aprender, mas ao mesmo tempo para utilizar.

porreiro

Andei a pesquisar muito, e a maioria da informação que encontro, fazem rivalidade entre o UDP e o TCP, dizem que um é mais rápido que o outro, etc... Dizem que utilizar os protocolos ao mesmo tempo pode meter a ligação mais lenta do que se fosse apenas UDP. E apontam para, quando se precisa de pacotes seguros, fazer uma costumização do UDP.

isso parece muita conversa de quem não percebe da coisa. é capaz de ter lido qualquer coisa aqui ou ali e já passou a ser um doutor da coisa (porque isto é um país de doutores).

os dois protocolos de comunicação existem e servem os seus propósitos.

se querem uma ligação em que a fiabilidade de chagada de informação é essencial, então usa TCP, caso contrário, usa o UDP.

se queres uma coisa intermédia usa os dois !!!.

Na verdade há algumas funcionalidades do TCP que eu não queria o tempo todo, como por exemplo a sequencialização dos pacotes, ou a ligação por stream que eu penso que tire um pouco de velocidade?

Mas eu não sou nenhum expert na coisa, e por isso não sei se conseguia fazer isto tudo como deve ser. O que é que me aconcelha? Utilizar os dois juntos não vai aumentar assim lá muito a latência?

pelo que dizes, o que queres fazer é como disse anteriormente, usa os dois.

terás de criar um protocolo ao nível da aplicação que usa pacotes vindos de duas portas (uma a usar o protocolo UDP e outra o protocolo TCP)

se necessitares, envia-me o teu código que eu dou uma vista de olhos

  • Voto 1

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
seuqram

Uhmm! Estou a ver. Assim a tarefa torna-se muito mais fácil :] Têm de ser necessáriamente em ports diferentes? Ou é pelo facto de ser mais rápido?

E esqueceu-se das aspas numas palavras aí que disse... eheh, e obrigado, Já me safou de muito tempo, que eu podia ter gasto a seguir essas informações da treta.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Uhmm! Estou a ver. Assim a tarefa torna-se muito mais fácil :] Têm de ser necessáriamente em ports diferentes? Ou é pelo facto de ser mais rápido?

sim, se queres usar os dois protocolos, tens de usar duas portas diferentes. uma porta configurada para usar o UDP e outra para o TCP.

e passa a ser da tua responsabilidade (ao nível da aplicação) a ordenação de pacotes entre as duas portas.

  • Voto 1

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
seuqram

Eu não quero estar a ser muito incomodativo mas eu tenho outro problema (sincronização do tcp com o udp) que eu não consigo resolver e não encontro nenhuma pista de como o fazer.

Anteriormente, eu tinha uma função que, quando recebia um pacote udp e se não houvesse nenhum usuário com o endereço do pacote, o servidor criava um novo usuário com esse novo endereço. Isto porque eu identificava facilmente o host e o port do client através do UDPpacket:

UDPpacket *p;
//...
User[...].host = p->address.host;
User[...].port = p->address.port;

Mas agora que instalei o tcp com o udp, tirei essa função, aceitando novas conexões com o SDLNet_TCP_Accept. Assim consigo criar sockets de tcp que liguem o servidor com o client, mas não consigo saber nada acerca da conexão udp. (O endereço remoto)

Eu já tentei a função: SDLNet_TCP_GetPeerAddress (no servidor) para saber o port do client, mas deu-me um port diferente do que me dá no UDPpacket. E também tentei o SDLNet_UDP_GetPeerAddress no client para saber o port e assim envia-lo para o servidor, só essa função só me dá o port local.

Se me conseguissem dar umas dicas, agradecia.

Editado por seuqram

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
seuqram

Eu andei a pesquisar muito... e eles dizem que se o client estiver por detrás do NAT, não vai ser possivel achar o port remoto sem haver troca de um packet de UDP. Eles estão certos?

Provavelmente vou ter que:

(server) enviar o numero de identificação para o client por tcp depois de ter aceitado a conexão.

(client) recebe o pacote, e até receber um segundo de tcp, vai enviar udps com o numero de identificação.

(server) recebe um de udp, e muda o port do usuário correspondente ao numero de identificação que recebeu no pacote.

Depois envia outro tcp para o client para parar de enviar udps e confirmar a conexão por udp.

O algoritmo está certo?

Editado por seuqram

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.