Ir para conteúdo
Fórum Script Brasil
  • 0

Multiplas Conexões Tcp


Lucas Phillip

Pergunta

Olá :D

gente, eu estou aprendendo agora vb.net e estou tentando fazer um servidor que aceite multiplas conexões. Bom eu consegui fazer o servidor conectar a um cliente, mas não consegui de jeito nenhum fazer multiplos clientes conectarem.

Eu até dei uma pesquisada no forum e achei algumas referencias sobre esse assunto, mas como ainda estou aprendendo, elas geraram mais duvidas que soluções.

Aqui está o codigo que utilizei para conectar o cliente e o servidor...

Try
            Listener = New TcpListener(addr, port)

            Listener.Start()

            While True

                'aceita conexão e configura
                Connection = Listener.AcceptSocket()

                socketStream = New NetworkStream(Connection)

                StreamOut = New BinaryWriter(socketStream)
                StreamIn = New BinaryReader(socketStream)

                StreamOut.Write("Conexão Sucedida")

como faço para o servidor aceitar multiplas conexões e saber diferencia-las uma da outra?

vlw :D

Link para o comentário
Compartilhar em outros sites

13 respostass a esta questão

Posts Recomendados

  • 0

Ao fazer...

Connection = Listener.AcceptSocket()

... você está aceitando a conexão e jogando a mesma para o objeto Connection. Se você fizer isso uma segunda vez, estará gerando *outra* conexão e assim por diante. Ou seja, cada objeto refere-se a uma conexão. Ou seja, fazendo um loop, você poderia aceitar múltiplas conexões. É interessante também usar o parâmetro backlog do método Start do seu objeto Listener para definir a quantidade de conexões pendentes (aguardando para serem aceitas).

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

aí gray,

vlw pela resposta, mas ainda to com problema..

o servidor está ate aceitando multiplas conexões... mas como eu faço para pode comunicar com os clientes conectados. porque quando uma pessoa conecta, o servidor envia msg atraves do objeto streamout... só que quando uma outra conecta, as duas conexão param de receber as msg enviadas pelo streamout...

eu pensei então que talvez se eu fizesse um array com o streamout para cada conexão desse, mas também não funcionou não :(

Link para o comentário
Compartilhar em outros sites

  • 0

Você está realmente utilizando objetos diferentes ou você está reaproveitando o mesmo objeto? Porque se for o segundo o caso, você vai estar perdendo a conexão anterior. E sim, a idéia é justamente usar uma estrutura de lista (como uma ArrayList) para guardar as conexões a fim de que depois você possa se comunicar com os clientes.

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

aew,

bom, o objeto para enviar já esta em um array e funciona.. o problema é para receber...

tava assim

            Do
                IncomeMessage = StreamIn.ReadString()

                Explode = Split(IncomeMessage, "|")

                Select Case (Explode(0))
                    Case "chat"

                        For X = 1 To (iUsers - 1)

                            StreamOut(X).Write(IncomeMessage)
                            StreamOut(X).Flush()

                        Next

                End Select

            Loop While True
ai desse jeito, enquanto apenas 1 usuario estivesse enviando, estava tudo bem, mas quando um outro enviava uma mensagem também, então a conexão era perdida. ai você falo pra coloca num array, e fiz isso, mas do jeito que eu fiz só "quase" funcionou... coloquei o "streamin" num array também, e para receber substitui
IncomeMessage = StreamIn.ReadString()
por
for y = 1 to (iusers -1)
IncomeMessage = StreamIn(y).ReadString()
next

bom, desse jeito, as vezes funcionava, as vezes não.. tinha mensagens que não chagavam, ai quando mandava uma outra, era a antiga que chegava...

bom, se não da pra usar o for pra verificar cada campo do array, como eu faço para verificar se um cliente mandou uma msg?

vlw :D

Link para o comentário
Compartilhar em outros sites

  • 0

No caso, uma das maneiras seria iniciar vários processos (threads), sendo um para cada cliente e no qual haveria o loop para o recebimento dos dados. Eu comecei a escrever um P2P (peer-to-peer, tipo eMule, KaZaA, etc.), em VB2005, no qual utilizei justamente essa técnica.

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

bom, to quase lá :D

eu tentei fazer o que você falou, mas surgiu um ultimo problema (pelo menos espero que seja)... eu criei uma thread para cada usuario que conectar.

só que na hora de receber, eu criei uma variavel que a cada thread vai aumentando em 1, para ir acompanhando as novas threads e ser o "numero" do usuario para receber... o problema é que quando eu aumento essa variavel, aumenta ela em todas as threads e acaba dando na mesma :P

como eu faço então pra fazer uma variavel, num array de threads, que vai aumentando, mas não aumenta em todas as threads, só na que ele foi "aumentado"?

vlw :D

Link para o comentário
Compartilhar em outros sites

  • 0

Aew,

bom, com a ajuda do Graymalking, eu consegui resolver meu problema de multiplas conexoes e ficou otimo... só ficou um problema... toda vez que uma pessoa nova conecta cria um usuario novo ela ao invés de reutilizar uma conexão livre, ela cria uma nova... ai o nº total de usuarios só vai aumentando infinitamente...

ai eu fiz um codigo que procura pelo numero de uma conexão fechada e utiliza ela para a proxima conexão... o problema é que não estou conseguindo passar esse numero para dentro das threads das conexões... antes eu tinha feito como o gray falou, declarei ela static e tava funcionando.. mas só estava funcionando porque como a cada conexao nova, simplesmente aumentava o valor de conexões +1, era só aumentar +1 ao "numero da conexao"... agora esse numero pode variar e como já disse, não to conseguindo pegar ele...

bom, vo posta aqui como tentei...

codigo para receber conexoes

 While True

                'aceita conexão e configura
                Connection(SocketLivre) = Listener.AcceptSocket()

                socketStream(SocketLivre) = New NetworkStream(Connection(SocketLivre))

                StreamOut(SocketLivre) = New BinaryWriter(socketStream(SocketLivre))
                StreamIn(SocketLivre) = New BinaryReader(socketStream(SocketLivre))

                SetText(iUsers)

                'inicia threads para comunicação
                ConThread(SocketLivre) = New Thread(AddressOf PlayersIO)
                ConThread(SocketLivre).Start()

                Dim AchouLivre As Boolean = False

                'acha socket livre
                If (iUsers > 1) Then

                    For Z = 1 To iUsers

                        Try

                            If (Connection(Z).Connected = False) Then

                                SocketLivre = Z
                                AchouLivre = True
                                Exit For

                            End If

                        Catch Null As NullReferenceException

                            'não faz nada...

                        End Try

                    Next

                End If

                'se não achar, adiciona novo usuario
                If (AchouLivre = False) Then

                    iUsers += 1
                    SocketLivre = iUsers

                End If

            End While
codigo das threads
 Public Sub PlayersIO()

(...)
        Dim InnerThread As Short

        InnerThread = SocketLivre - 1

(...)
End Sub

alguém sabe me ajuda?? vlw :D

Link para o comentário
Compartilhar em outros sites

  • 0

com certeza... mas o que eu reparei era o seguinte: no loop para aceitar conexões, se eu colocava uma msgbox antes da linha "Connection(SocketLivre) = Listener.AcceptSocket()" a msg aparecia na hora de carregar o programa.. se eu colocava depois, a msg só aparecia na hora que recebia uma conexão..

então eu conclui que no loop, ao chegar em "Connection(SocketLivre) = Listener.AcceptSocket()", ele parava o loop e ficava esperando ate receber uma conexão para continuar...

ai acabo que deu na mesma se eu coloco para procurar antes ou depois, porque mesmo eu colocando antes, depois que receber a 1 conexão, ele já vai preparar a 2 segunda conexão como não tendo ninguém... eu só coloquei pra procurar a conexao depois de aceitar porque tava fazendo testes e fico assim minha ultima tentativa (que o resultado deu exatamente o mesmo quando coloquei pra procurar antes)

deu pra entender? :D

Link para o comentário
Compartilhar em outros sites

  • 0

aew... bom, acho que to quase la :blink:

agora eu só não to sabendo fechar as conexões para que elas sejam reutilizadas por outros usuarios..

está assim:

 Dim AchouLivre As Boolean = False

                'acha socket livre
                If (iUsers > 1) Then

                    For Z = 1 To iUsers

                        Try

                            If (Connection(Z).Connected = False) Then

                                SocketLivre = CShort(Z)
                                AchouLivre = True
                                Exit For

                            End If

                        Catch Null As NullReferenceException

                            'não faz nada...

                        End Try

                    Next

                End If

                'se não achar, adiciona novo usuario
                If (AchouLivre = False) Then

                    iUsers = CShort(iUsers + 1)
                    SocketLivre = iUsers

                End If

                'aceita conexão e configura
                Connection(SocketLivre) = Listener.AcceptSocket()

                socketStream(SocketLivre) = New NetworkStream(Connection(SocketLivre))

                StreamOut(SocketLivre) = New BinaryWriter(socketStream(SocketLivre))
                StreamIn(SocketLivre) = New BinaryReader(socketStream(SocketLivre))

                'inicia threads para comunicação
                ConThread(SocketLivre) = New Thread(AddressOf PlayersIO)
                ConThread(SocketLivre).Start(SocketLivre)
e para fechar a conexão
        Connection(QualThread).Close()
        socketStream(QualThread).Close()

        StreamOut(QualThread).Close()
        StreamIn(QualThread).Close()

        ConThread(QualThread).Abort()

eu na verdade não tinha muito ideia de como fazer para fechar as conexões então tentei desse jeito ai em cima.. mas assim não funciona.. qual o jeito correto de fazer isso?

vlw

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,8k
×
×
  • Criar Novo...