Jump to content

SDL_net server-client


seuqram
Go to solution Solved by HappyHippyHippo,

Recommended Posts

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.

Edited by pwseo
removida formatação desnecessária
Link to comment
Share on other sites

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.

  • Vote 1
IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

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.

Edited by seuqram
Link to comment
Share on other sites

  • Solution

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

  • Vote 1
IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

  • Vote 1
IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

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.

Edited by seuqram
Link to comment
Share on other sites

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?

Edited by seuqram
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.