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

Chat em Visual Basic


Darknnez

Pergunta

Foi mal, não consegui pensar em um título adequado pra minha dúvida.

O negócio é o seguinte.

Eu fiz uma chat no VB6.

Em um TextBox, o usuário escreve a mensagem que é salva em um arquivo.txt:

Private Sub Command1_Click()
Set txt = FSO.OpenTextFile("\\Lucas\C\ChatLog.txt", ForAppending)
If Destinatário.Caption = "Todos" Then
    txt.WriteLine (Nick + " diz: " + Mensagem.Text + vbCr)
    txt.Close
Else
    txt.WriteLine (Nick + " fala para " + Destinatário.Caption + " " + Mensagem.Text + vbCr)
    txt.Close
End If
Mensagem.Text = ""
End Sub
Um segundo TextBox lê todo o conteúdo desse arquivo.txt, e é atualizado por um Timer:
Private Sub Timer1_Timer()
Set txt = FSO.OpenTextFile("\\Lucas\C\ChatLog.txt", ForReading)
Caixa.Text = txt.ReadAll
txt.Close

Caixa.SelStart = Len(Caixa.Text)
Destinatário.Caption = Usuários.Text
End Sub

O que eu queria fazer é que nesse segundo TextBox o nick do usuário aparecesse colorido, de acordo com a cor selecionada pelo usuário. Mas tem como fazer isso, ou seja, alterar a cor de apenas uma parte do texto?

Link para o comentário
Compartilhar em outros sites

  • Respostas 54
  • Created
  • Última resposta

Top Posters For This Question

Posts Recomendados

  • 0

bom, imagino q você esteja passando o ip do computador em vez do texto "Meu IP", certo??

mas no outro pc, ta o programa rodando com um listen no localport com o mesmo numero da porta q você ta passando no cliente??

se tiver, então tenta, no cliente, em vez de usar a propriedade RemoteHostIP, passe o nome do pc servidor na propriedade RemoteHost.

Link para o comentário
Compartilhar em outros sites

  • 0
bom, imagino q você esteja passando o ip do computador em vez do texto "Meu IP", certo??

Sim

mas no outro pc, ta o programa rodando com um listen no localport com o mesmo numero da porta q você ta passando no cliente??

se tiver, então tenta, no cliente, em vez de usar a propriedade RemoteHostIP, passe o nome do pc servidor na propriedade RemoteHost.

Mas foi o que eu fiz.

Eu disse:

Então eu tentei me conectar pelo nome do computador em vez do IP, e deu certo.

Esse problema eu consegui resolver, mas os outros dois que eu falei no último post permanecem.

Link para o comentário
Compartilhar em outros sites

  • 0

é mas tenta usar a propriedade RemoteHost e não RemoteHostIP, você já fez isso??

o terceiro erro acredito q ocorre porque ele não conectou com o servidor.

tipo cheque a propriedade State do winsock cliente. se for 7 significa q esta conectado, veja a lista de states q o macoratti passa aqui: http://www.macoratti.net/winsock.htm

talvez na verdade ele ate conecte, mas como você ta pondo a linha pra mandar a mensagem logo depois do connect, pode ser q ele esteja com o status 6 (conectando) e ai ele vai dar esse erro, pois demora um poco pra conectar.

tenta, depois do connect chamar um timer q cheque o state do winsock cliente. se chegar em 7, você da esses senddata, desabilita o timer e poe o programa pra funcionar. caso chegue em 9 (erro) é porque não conseguiu conectar, ai nesse caso posta aqui de novo.

Link para o comentário
Compartilhar em outros sites

  • 0
é mas tenta usar a propriedade RemoteHost e não RemoteHostIP, você já fez isso??
Sim.

tenta, depois do connect chamar um timer q cheque o state do winsock cliente. se chegar em 7, você da esses senddata, desabilita o timer e poe o programa pra funcionar. caso chegue em 9 (erro) é porque não conseguiu conectar, ai nesse caso posta aqui de novo.

Na primeira vez que eu tentei parece que deu certo.

Os dados foram transferidos e apareceram no TextBox do Servidor.

Mas só funcionou esse vez.

Depois não conseguiu conectar, e o state do winsock cliente chegou a 9.

Edit:

Testei agora mais algumas vezes, e todas deram certo.

Não mudei nadinha no código.

Edit:

É, parece mesmo que está dando certo.

Só um dúvida.

Quando eu mando enviar o número da porta local do cliente, para o servidor, sempre aparece uma coisa completamente diferente no TextBox do servidor, quando ele recebe os dados.

Por exemplo: eu enviei o valor da porta 100, e apareceu um 'd' no TextBox.

Depois enviei a porta 300, e apareceu um `.l`.

Por que isso acontece?

Editado por Darknnez
Link para o comentário
Compartilhar em outros sites

  • 0
Por que isso acontece?

primeiro note q a porta 100 na verdade é a RemotePort do cliente e não a local.

você mandou ele procurar a porta 100 aberta no servidor, mas imagino q ele deva abrir uma porta random no cliente pra poder fazer a conexao e é esse valor q você ta passando pro servidor.

o numero ta cehgando estranho, imagino porque você deve estar pegando os dados como string do outro lado não??

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
  Dim x As String
  Winsock1.GetData x, vbString
  Text1.Text = x
End Sub[/code]

tipo isso q você ta fazendo não??

mas se você entrar nas propriedades do Winsock (F2 ou, no codigo, clique com o botao direito onde estiver escrito LocalPort como propriedade do winsock e clique en Definition) você vai ver q o LocalPort na verdade é do tipo Long, você não vai conseguir ler como String.

ou você converte pra String com CStr() antes de mandar, ou você da um GetData como vbLong, mas acho q a primeira opcao seria melhor já q imagino q você va passar varias strings no SendData.

Link para o comentário
Compartilhar em outros sites

  • 0

Estou com algumas dúvidas.

A primeira é, quando eu faço

wskServidor.SendData Dados

o winsock Servidor manda o conteúdo da variável Dados para todos Clientes que estiverem conectados à ele?

E a segunda, é por que ás vezes o State do winsock Cliente chega a 7, e outras à 9?

Tipo, quais fatores influenciam isso?

Por que as vezes eu consigo fazer a conexão, e ás vezes não.

Meio que varia, e não parece ter uma lógica.

Link para o comentário
Compartilhar em outros sites

  • 0
A primeira é, quando eu faço

wskServidor.SendData Dados

o winsock Servidor manda o conteúdo da variável Dados para todos Clientes que estiverem conectados à ele?

manda sim. mas todos os Clientes é só um Cliente, você não consegue conectar dois clientes no mesmo objeto winsock.

bom, pelo menos eu nunca consegui, acho q o winsock não deixa mesmo, tb porque depois q a primeria conexao chega, você para o listen e conecta com o cliente. pra fazer outro listen o esquema q eu arranjei é criar um array de winsocks e cada conexao q chegar no servidor, adicionar um winsock novo no form e dar o listen. não precisa nem mudar a porta.

ai quando for mandar a mensagem você faz um for e manda pra todos os clientes.

E a segunda, é por que ás vezes o State do winsock Cliente chega a 7, e outras à 9?

Tipo, quais fatores influenciam isso?

sei la, pode ser falha na comunicao dos seus pcs sei la. talvez seja porque você tentou abrir quando tava uma outra instancia aberta do servidro ou do cliente. é muito frequente dar 9??

Link para o comentário
Compartilhar em outros sites

  • 0
manda sim. mas todos os Clientes é só um Cliente, você não consegue conectar dois clientes no mesmo objeto winsock.

bom, pelo menos eu nunca consegui, acho q o winsock não deixa mesmo, tb porque depois q a primeria conexao chega, você para o listen e conecta com o cliente. pra fazer outro listen o esquema q eu arranjei é criar um array de winsocks e cada conexao q chegar no servidor, adicionar um winsock novo no form e dar o listen. não precisa nem mudar a porta.

ai quando for mandar a mensagem você faz um for e manda pra todos os clientes.

Entendi.

Como que faz pra criar um array de winsocks?

E como eu faço pra saber quando a conexão chega?

sei la, pode ser falha na comunicao dos seus pcs sei la. talvez seja porque você tentou abrir quando tava uma outra instancia aberta do servidro ou do cliente. é muito frequente dar 9??

Mais ou menos 50% das vezes.

Editado por Darknnez
Link para o comentário
Compartilhar em outros sites

  • 0
Como que faz pra criar um array de winsocks?

no design do form, copie o controle Winsock, cole e quando ele perguntar "Do you want to create a control array?", clique em Sim. e ai sempre q você adicionar um novo você vai ter um indice a mais do array.

mas você pode apagar o segundo winsock q apareceu e adicionar os demais via codigo assim:

Load Winsock1(novo_indice)
E como eu faço pra saber quando a conexão chega?
na sub ConnectionRequest. acredito q você esteja usando-a pra aceitar a conexao, não??
sei la, pode ser falha na comunicao dos seus pcs sei la. talvez seja porque você tentou abrir quando tava uma outra instancia aberta do servidro ou do cliente. é muito frequente dar 9??
Mais ou menos 50% das vezes.
sei la, talvez porque você feche o programa mas o Winsock antigo continue na memoria. no Unload do Form, tente adicionar o codigo:
Winsock1.Close
    Set Winsock1 = Nothing[/code]

Link para o comentário
Compartilhar em outros sites

  • 0

Não entendi muito bem como faço para adicionar um novo winsock a cada conexão.

Tipo, eu tenho um winsock, chamado wskServidor.

Eu setei o Index do wskServidor para 0.

Aí na sub ConnectionRequest, eu tenho que fazer isso?

Private Sub wskServidor_ConnectionRequest(ByVal requestID As Long)
   If wskServidor.State <> sckClosed Then wskServidor.Close
   wskServidor.Accept requestID
   
   Load wskServidor(1)
End Sub

Por que se for, dá um erro.

Aparece a mensagem:

Procedure declaration does not match description of event or procedure having the same name

Link para o comentário
Compartilhar em outros sites

  • 0

acontece q agora sempre q você for usar o controle Winsock você vai ter q passar o indice ao q se refere. o mesmo vale pros eventos, pois os eventos ocorrem pra cada indice e não para todos.

tipo recorta todo o codigo q esta dentro do ConnectionRequest, apague a sub ConnectionRequest e a chame de novo q ai ele vai montar o codigo certinho, passando como o parametro o Index do controle onde ocorre o evento.

faca o mesmo pros outros eventos do Winsock q você tiver.

Link para o comentário
Compartilhar em outros sites

  • 0

Deu certo.

Então só pra ver se eu entendi direito.

Cada vez que um cliente tentar se conectar, um novo winsock servidor será criado, e é à esse novo winsock que o cliente vai se conectar?

E as propriedades, como a porta, de cada winsock criado são iguais às propriedades do primeiro winsock, ou eu tenho que setá-las para cada winsock?

Link para o comentário
Compartilhar em outros sites

  • 0
Cada vez que um cliente tentar se conectar, um novo winsock servidor será criado, e é à esse novo winsock que o cliente vai se conectar?

é tipo, o programa comeca e você tem só um Winsock com Listen. cehga a primeira conexao, esse primeiro Winsock conecta e um novo Winsock é adicionado e fica esperando outra conexao. ai chega mais uma conexao, ai o ultimo Winsock conecta, e um novo é adicionado e fica escutando e assim por diante.

E as propriedades, como a porta, de cada winsock criado são iguais às propriedades do primeiro winsock, ou eu tenho que setá-las para cada winsock?

acho q tem q setar a porta sim. mas pode ser a mesma porta, já q como ela esta sendo usada pela mesma aplicacao, não deve dar conflito.

Link para o comentário
Compartilhar em outros sites

  • 0
sei la, talvez porque você feche o programa mas o Winsock antigo continue na memoria. no Unload do Form, tente adicionar o codigo:

Winsock1.Close
    Set Winsock1 = Nothing

Não deu certo.

O state do winsock cliente continua chegando à 9.

E quando eu mando fechar o form com o winsock servidor, dá um erro na linha Set wskServidor = Nothing, e aparece a mensagem de erro: Invalid use of property.

Link para o comentário
Compartilhar em outros sites

  • 0

opa é verdade o Nothing não vai funcionar no Winsock.

mas sei la, fiz uns testes aqui e não deu 9 nenhuma vez aqui na rede do trampo. só posso imaginar q seja alguma coisa na sua rede, sei la.

no programa servidor, na hora de dar o close tb, faz um for e de close em todos os indices, talvez ajude.

Link para o comentário
Compartilhar em outros sites

  • 0

É.... eu já tinha feito isso.

Não tem jeito mesmo.

Mas o que eu notei é que eu devo esperar um tempinho, aproximadamente 1 minuto, depois de fechar o servidor.

Assim não dá problema.

Mas se eu tentar me conectar logo após fechar, sempre vai dar State = 9.

Agora mais um probleminha:

Eu fiz o seguinte no form load do chat:

For i = 0 To 19
    If Escolha = xSala(i).Nome Then
        If xPerfil.Nick = xSala(i).Admin Then
            Dim wskAdmin2 As Winsock
            wskAdmin2.LocalPort = xSala(i).Porta
            Exit For
        Else
            Dim wskCliente2 As Winsock
            wskCliente2.RemoteHost = xSala(i).PC
            wskCliente2.RemotePort = xSala(i).Porta
            wskCliente2.Connect
            TimerCliente.Enabled = True
            Exit For
        End If
    End If
Next
Esse código confere se o usuário é o administrador da sala (servidor) ou o cliente. Aí eu tentei criar a sala e entrar nela como administrador, mas deu um erro na linha:
wskAdmin2.LocalPort = xSala(i).Porta

E apareceu a mensagem de erro:

Object variable or With block variable not set.

O que isso quer dizer?

Qual o erro?

Link para o comentário
Compartilhar em outros sites

  • 0
Mas o que eu notei é que eu devo esperar um tempinho, aproximadamente 1 minuto, depois de fechar o servidor.

Assim não dá problema.

nesse caso, no Unload, tenta então finalizar o form. tipo assim

Set Form1 = Nothing
Esse código confere se o usuário é o administrador da sala (servidor) ou o cliente. Aí eu tentei criar a sala e entrar nela como administrador, mas deu um erro na linha:
wskAdmin2.LocalPort = xSala(i).Porta
E apareceu a mensagem de erro: Object variable or With block variable not set. O que isso quer dizer? Qual o erro?
é isso q você ta fazendo não vai funcionar mesmo, já q o Winsock q você cria não esta carregado. mas você não ta trabalhando com array de winsock?? é bem mais facil trabalhar assim, ai é só dar o Load pra adicionar um novo. pra criar o controle em tempo de execucao é bem mais trampo, mas pra adicionar tem q ser assim:
Dim wskAdmin2 As Winsock

Set wskAdmin2 = Controls.Add("MSWinsock.Winsock.1", "wskAdmin2", Form1)[/code] onde Form1 é o nome do seu formulario. ai das proximas vezes q você precisar acessar esse controle Winsock, não acesse pela variavel e sim pelo controle no form tipo assim:
[code]Me.Controls("wskAdmin2").LocalPort = xSala(i).Porta

Link para o comentário
Compartilhar em outros sites

  • 0

Mas se eu usar o Load pra criar o winsock, já tem que existir um winsock no form, ou não?

Na verdade nem sei por que estou fazendo desse jeito.

Eu posso criar apenas um winsock no form, e dependendo se o usuário for o administrador da sala ou o cliente, mudar as propriedades do winsock conforme necessário. Certo?

Link para o comentário
Compartilhar em outros sites

  • 0
Mas se eu usar o Load pra criar o winsock, já tem que existir um winsock no form, ou não?

tem. e tem q ser um array.

Eu posso criar apenas um winsock no form, e dependendo se o usuário for o administrador da sala ou o cliente, mudar as propriedades do winsock conforme necessário. Certo?

não entendi o q você quis dizer.

cada winsock suporta apenas uma conexao. por isso você precisa de outros, senao você vai ter sempre só um usuario no seu chat falando sozinho hahaha.

Link para o comentário
Compartilhar em outros sites

  • 0
não entendi o q você quis dizer.

cada winsock suporta apenas uma conexao. por isso você precisa de outros, senao você vai ter sempre só um usuario no seu chat falando sozinho hahaha.

huahaha

É, foi uma idéia infeliz.

Mas eu consegui fazer aqui.

O problema agora é que eu não consigo fazer o usuário (cliente) se conectar ao administrador da sala (servidor).

Eu fiz uns testes aqui e, primeiramente, o Timer:

Private Sub TimerCliente_Timer()
If wskCliente2.State = 7 Then
    Dados = "Perfil" & "#" & xPerfil.Nick & "#" & xPerfil.Cor & "#" & xPerfil.Fonte & "#" & xPerfil.Bold & "#" & xPerfil.Italic & "#"
    wskCliente2.SendData Dados
    MsgBox "Conectado ao servidor"
    TimerCliente.Enabled = False
ElseIf wskCliente2.State = 9 Then
    MsgBox "Não foi possível se conectar", vbInformation, "Erro"
End If
End Sub

fica rodando um tempão, com State = 6.

E depois dá State = 9.

Ou seja, eu consegui fazer o cliente se conectar ao servidor principal (meu PC) para criar a sala ou achar as salas criadas. Mas não consigo fazer que, a partir daí, o cliente que criou a sala (administrador) se torne o servidor, e os outros clientes se conectem diretamente à ele, e não ao meu PC.

Quais são as possíveis explicações pra isso?

Editado por Darknnez
Link para o comentário
Compartilhar em outros sites

  • 0

Não seria melhor usar os próprios eventos do Winsock ao invés de um Timer, pelo menos para essa conexão inicial? E, também fica mais fácil de entender se você usar as constantes (sckConnecting, sckConnected, sckError, etc.) ao invés dos valores (6, 7, 9, etc.), não?

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

Opa!

Bem... o timer serve pra esperar o winsock fazer a conexão.

Se eu enviar os dados logo após mandar conectar, vai dar erro, por que o state ainda vai estar igual à 6 (sckConnecting).

Então o timer funciona até dar state = 7 (sckConnected), e só então envia os dados.

No caso, o problema que estou tendo é que o state nem sequer está chegando à 7.

Ele tenta conectar, e logo depois (imagino eu) pula para state = 9 (sckError).

E eu não sei como resolver...

Link para o comentário
Compartilhar em outros sites

  • 0

Você está tentando se conectar a outro computador na rede local? Ou ao seu próprio? Ou a outro via Internet?

Quanto ao timer para conectar, eu uso um loop normal, como você pode ver no meu tutorial sobre Winsock: http://desenvolvedores.net/modules.php?nam...icle&sid=27

Abraços,

Graymalkin

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
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...