[Cramel] Gestión de conexiones [Ejemplo + Source]

Iniciado por BlackBlex, Julio 05, 2017, 10:42:32 PM

Tema anterior - Siguiente tema

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

Les traigo el siguiente ejemplo o ejercicio sobre sockets, en este caso les traigo un gestor de pc (clientes), en el cual podremos abrirle la disquera y cerrarsela.





Nota: el ejemplo es algo básico, y podemos decir que podría ser los principios de un "Troyano" al tener un servidor que se pone en escucha, y un cliente que se intenta conectar a X ip, con X puerto; Igual cabe recalcar que puede ser inestable en el uso de esté.



Código fuente del Servidor.cml

Información

Archivo Servidor.cml
Código: Cramel
'/**
' * Servidor del gestor de conexiones
' *
' * @author  Jovani Pérez Damián (@BlackBlex)
' *
' * ==============Information==============
' *      Filename: Servidor.cml
' * ---------------------------------------
'*/

Importar "Cramel.cml"
Importar "MSVBVM60\MSVBVM60.cml"
Importar "Propio\Cramel2\Sockets\Socket.cml"
Importar "Propio\Cramel2\Interfaz\Interfaz.cml"

Var Server:SocketServer

Var clientesSocket[]:Entero
Var clientesName[]:Cadena
ReDim clientesSocket, 1
ReDim clientesName, 1

Var ServerIniciado:Booleano
ServerIniciado = Falso

Var frame:CMLframe
Var listViewConectados:CMLListview
Var botonAbrirCD, botonCerrarCD:CMLBotón

Proc iniciarServer
    Repetir
        Var connections, newConnect:Entero
        Var infoThread:Cadena
        newConnect = Server.aceptar
        infoThread = EntCad(newConnect) + "|" + EntCad(connections)
        clientesSocket[connections] = newConnect
        CreateThread(Nulo, 0, ServerManager@, StrPtr(infoThread), 0, 0)
        connections = connections + 1
        ReDim Preservar clientesSocket, (connections+1)
    PorSiempre
FinProc

Proc frameEventoGanarFoco(hWnd:Entero)
    Si ( ServerIniciado = Falso ) Entonces
        ServerIniciado = Verdad
        CreateThread(Nulo, 0, iniciarServer@, Nulo, 0, 0)
    FinSi
FinProc

Proc frameEventoTerminar(hWnd:Entero, Referencia Cancelar:Booleano)
    Server.detener
FinProc

Crear Server
Crear frame
Crear listViewConectados
Crear botonAbrirCD
Crear botonCerrarCD

    Server.iniciar
    Si (Server.escuchar(666) = SOCKET_ERROR) Entonces
        Mensaje("Error al iniciar el socket")
        ExitProcess(0)
    SiNo
        frame.Texto = "Gestor de conexiones - En escucha"
        frame.Ancho = 700
        frame.Alto = 400
        frame.Padre = 0
        frame.Centrar = 1
        frame.eventos.GanarFoco@ = frameEventoGanarFoco@
        frame.eventos.Terminar@  = frameEventoTerminar@
        frame.construir(WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU)

        listViewConectados.PosX  = 10
        listViewConectados.PosY  = 10
        listViewConectados.Ancho = frame.Ancho - 30
        listViewConectados.Alto  = frame.Alto - 100
        listViewConectados.Padre = frame.hWnd
        listViewConectados.fuente.Nombre = "Arial"
        listViewConectados.fuente.Tamaño = 11
        listViewConectados.construir()

        Var listColumnas[]:INFO_COLUMNA
        ReDim listColumnas, 5

        listColumnas[0].Indice   = 0
        listColumnas[0].Ancho    = (listViewConectados.Ancho/5)
        listColumnas[0].Posición = LVCFMT_LEFT
        listColumnas[0].Texto    = "Nombre"

        listColumnas[1].Indice   = 1
        listColumnas[1].Ancho    = (listViewConectados.Ancho/5)
        listColumnas[1].Posición = LVCFMT_CENTER
        listColumnas[1].Texto    = "Dirección IP"

        listColumnas[2].Indice   = 2
        listColumnas[2].Ancho    = (listViewConectados.Ancho/5)
        listColumnas[2].Posición = LVCFMT_CENTER
        listColumnas[2].Texto    = "Usuario@Host"

        listColumnas[3].Indice   = 3
        listColumnas[3].Ancho    = (listViewConectados.Ancho/5)
        listColumnas[3].Posición = LVCFMT_CENTER
        listColumnas[3].Texto    = "SO"

        listColumnas[4].Indice   = 4
        listColumnas[4].Ancho    = (listViewConectados.Ancho/5)
        listColumnas[4].Posición = LVCFMT_CENTER
        listColumnas[4].Texto    = "País@Idioma"

        listViewConectados.insertarColumnas(listColumnas)

        botonAbrirCD.Texto = "Abrir CD"
        botonAbrirCD.PosX  = 10
        botonAbrirCD.PosY  = frame.Alto - 80
        botonAbrirCD.Ancho = (frame.Ancho/2) - 30
        botonAbrirCD.Alto  = 40
        botonAbrirCD.Padre = frame.hWnd
        botonAbrirCD.eventos.Mouse.Clic@ = botonAbrirCDEventClic@
        botonAbrirCD.construir()

        botonCerrarCD.Texto = "Cerrar CD"
        botonCerrarCD.PosX  = (frame.Ancho - botonAbrirCD.Ancho) - 20
        botonCerrarCD.PosY  = botonAbrirCD.PosY
        botonCerrarCD.Ancho = (frame.Ancho/2) - 30
        botonCerrarCD.Alto  = 40
        botonCerrarCD.Padre = frame.hWnd
        botonCerrarCD.eventos.Mouse.Clic@ = botonCerrarCDEventClic@
        botonCerrarCD.construir()

        frame.mostrar()
        frame.correr()
    FinSi

Proc botonAbrirCDEventClic(hWnd:Entero,Botón:Byte,Presionado:Booleano,X,Y:Entero)
    Seleccionar Botón
        Caso BOTON_IZQUIERDO
            Seleccionar Presionado
                Caso Falso
                    Var seleccionado, iCount, clienteSocket:Entero
                    Var seleccionadoTxt:Cadena
                    seleccionado = listViewConectados.getItemSelected

                    Si ( seleccionado <> -1 ) Entonces
                        seleccionadoTxt = listViewConectados.getItemText(seleccionado, 0)
                        Contar iCount a &clientesName
                            Si ( seleccionadoTxt = clientesName[iCount] ) Entonces
                                clienteSocket = clientesSocket[iCount]
                                Salir Contar
                            FinSi
                        Seguir

                        Si ( clienteSocket <> 0 ) Entonces
                            Server.enviar(clienteSocket, "openCD|0")
                        FinSi
                    FinSi
            FinSeleccionar
    FinSeleccionar
FinProc

Proc botonCerrarCDEventClic(hWnd:Entero,Botón:Byte,Presionado:Booleano,X,Y:Entero)
    Seleccionar Botón
        Caso BOTON_IZQUIERDO
            Seleccionar Presionado
                Caso Falso
                    Var seleccionado, iCount, clienteSocket:Entero
                    Var seleccionadoTxt:Cadena
                    seleccionado = listViewConectados.getItemSelected

                    Si ( seleccionado <> -1 ) Entonces
                        seleccionadoTxt = listViewConectados.getItemText(seleccionado, 0)
                        Contar iCount a &clientesName
                            Si ( seleccionadoTxt = clientesName[iCount] ) Entonces
                                clienteSocket = clientesSocket[iCount]
                                Salir Contar
                            FinSi
                        Seguir

                        Si ( clienteSocket <> 0 ) Entonces
                            Server.enviar(clienteSocket, "closeCD|0")
                        FinSi
                    FinSi
            FinSeleccionar
    FinSeleccionar
FinProc

Proc ServerManager(info:Entero)
    Var IDclient, idConnect:Entero
    Var infoCad:Cadena
    Var msg, arrayInfo[]:Cadena
    infoCad = CadDePtr(info)
    arrayInfo = Separar(infoCad, "|")
    IDclient = CadEnt(arrayInfo[0])
    idConnect = CadEnt(arrayInfo[1])
    Repetir
        msg = Server.recibir(IDclient)
        Si ( (CadLong(msg) = 0) Or (msg = "") ) Entonces Salir Repetir
        arrayInfo = Separar(msg, "|")
        Seleccionar arrayInfo[0]
            Caso "registro"
                registroCliente(idConnect, arrayInfo[1])
            Caso "salir"
                Server.desconectar(IDclient)
                'Server.enviar(IDclient, "salir")
                Salir Repetir
        FinSeleccionar
        Pausar(500)
    PorSiempre
    clientesSocket[idConnect] = 0
    Var i:Entero
    i = 0
    Contar i a listViewConectados.ItemsCount
        Var itemComp:Cadena
        itemComp = "ServerTest" + EntCad(idConnect)
        Si ( listViewConectados.getItemText(i, 0) = itemComp ) Entonces
            listViewConectados.eliminarItem(i)
            Salir Contar
        FinSi
    Seguir
    'ExitThread(0)
FinProc

Proc registroCliente(id:Entero, txt:Cadena)
    Var listItems:INFO_ITEM
    Var info[]:Cadena
    ReDim listItems.Texto, 5
    info = Separar(txt, "=.=")
    listItems.Texto[0] = info[0] + EntCad(id)
    listItems.Texto[1] = info[1]
    listItems.Texto[2] = info[2]
    listItems.Texto[3] = info[3]
    listItems.Texto[4] = info[4]
    listItems.Indice   = id
    clientesName[id] = listItems.Texto[0]
    listViewConectados.insertarItem(listItems)
    ReDim Preservar clientesName, (id+2)
FinProc

Destruir botonCerrarCD
Destruir botonAbrirCD
Destruir listViewConectados
Destruir frame
Destruir Server




Código fuente del Cliente.cml

Información

Archivo Cliente.cml
Código: Cramel
'/**
' * Cliente del gestor de conexiones
' *
' * @author  Jovani Pérez Damián (@BlackBlex)
' *
' * ==============Information==============
' *      Filename: Cliente.cml
' * ---------------------------------------
'*/

Importar "Cramel.cml"
Importar "MSVBVM60\MSVBVM60.cml"
Importar "Constantes.cml"
Importar "APIS.cml"
Importar "Socket.cml"
Importar "Interfaz\Interfaz.cml"
Importar "HTTPRequest.cml"
Importar "Regedit.cml"
Importar "Funciones.cml"

Var Cliente:SocketClient
Var frame:CMLframe
Var hilo, hiloID:Entero

Proc frameEventoCargar(hWnd:Entero)
    Var info[]:Cadena
    info = obtenerIPPais
    Cliente.enviar("registro|ServerTest=.=" + info[0] + "=.=" + Usuario + "@" + UsuarioDominioSO + "=.=" + SO + "=.=" + info[1] + "@" + LenguajeSO)
FinProc

Proc frameEventoTerminar(hWnd:Entero, Referencia Cancelar:Booleano)
    Cliente.enviar("salir|0")
    Cliente.detener
    ExitProcess(0)
FinProc

Crear Cliente
Crear frame
    Cliente.iniciar
    Si (Cliente.conectar("127.0.0.1", 666) = SOCKET_ERROR) Entonces
        Mensaje("Error al iniciar conectarse al servidor")
        ExitProcess(0)
    SiNo
        hilo = CreateThread(Nulo, 0, ClienteManager@, Nulo, 0, hiloID@)

        frame.Texto = "Cliente en espera"
        frame.PosX  = 10
        frame.PosY  = 10
        frame.Ancho = 100
        frame.Alto  = 100
        frame.Padre = 0
        frame.eventos.Cargar@  = frameEventoCargar@
        frame.eventos.Terminar@  = frameEventoTerminar@
        frame.construir(WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU)

        frame.mostrar()
        frame.correr()
    FinSi

Proc ClienteManager
    Var msg[],tempMsg:Cadena
    Var command,empty:Cadena
    Repetir
        tempMsg = Cliente.recibir
        Si ( (CadLong(tempMsg) = 0) Or (tempMsg = "") ) Entonces Salir Repetir
        msg = Separar(tempMsg, "|")
        Seleccionar msg[0]
            Caso "Hola"
                Cliente.enviar("c")
            Caso "openCD"
                command = "set CDAudio door open"
                mciSendString(StrPtr(command), StrPtr(empty), 127, 0)
            Caso "closeCD"
                command = "set CDAudio door closed"
                mciSendString(StrPtr(command), StrPtr(empty), 127, 0)
        FinSeleccionar
        Pausar(500)
    PorSiempre
FinProc

Destruir frame
Destruir Cliente


Archivo Funciones.cml
Código: Cramel
'/**
' * Funciones
' *
' * @author  Jovani Pérez Damián (@BlackBlex)
' *
' * ==============Information==============
' *      Filename: Constantes.cml
' * ---------------------------------------
'*/

Proc SO():Cadena
    Var registro:Regedit
    Crear registro
    registro.hClave = HKEY_LOCAL_MACHINE
    registro.sClave = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
    registro.Clave  = "ProductName"
    Resultado = registro.leerClaveCadena
    Destruir registro   
FinProc

Proc Usuario():Cadena
    Var len:Entero
    len = MAX_PATH
    Resultado = Espacio(len)
    GetUserName(StrPtr(Resultado), len@)
    Resultado = TruncarCadena(Resultado)
FinProc

Proc LenguajeSO():Cadena
    Var registro:Regedit
    Crear registro
    registro.hClave = HKEY_CURRENT_USER
    registro.sClave = "Control Panel\\International"
    registro.Clave  = "LocaleName"
    Resultado = registro.leerClaveCadena
    Destruir registro   
FinProc

Proc UsuarioDominioSO():Cadena
    Var registro:Regedit
    Crear registro
    registro.hClave = HKEY_CURRENT_USER
    registro.sClave = "Volatile Environment"
    registro.Clave  = "USERDOMAIN"
    Resultado = registro.leerClaveCadena
    Destruir registro   
FinProc

Proc UsuarioPathSO():Cadena
    Var registro:Regedit
    Crear registro
    registro.hClave = HKEY_CURRENT_USER
    registro.sClave = "Volatile Environment"
    registro.Clave  = "USERPROFILE"
    Resultado = registro.leerClaveCadena
    Destruir registro   
FinProc

Proc obtenerIPPais:Cadena[]
    Var request:HTTP
    Crear request
        request.Metodo = "GET"
        request.Puerto = INTERNET_DEFAULT_HTTP_PORT
        request.Servidor = "aruljohn.com"
        request.Dirección = "/details.php"
        Var codigoFuente,partes[]:Cadena
        ReDim Resultado, 2

        Si ( request.Conectar ) Entonces
            Si ( request.Enviar ) Entonces
                Si ( request.StatusCode = HTTP_STATUS_OK ) Entonces
                    codigoFuente = request.LeerRespuesta

                    'IP'
                    partes = Separar(codigoFuente, "IP address</td><td>")
                    partes[0] = partes[1]
                    partes = Separar(partes[0], "</td></tr>")
                    Resultado[0] = TruncarCadena(partes[0])
                    'País'
                    partes = Separar(codigoFuente, "Country</td><td valign=\"top\">")
                    partes[0] = partes[1]
                    partes = Separar(partes[0], "<img src=")
                    Resultado[1] = TruncarCadena(partes[0])
                FinSi
            FinSi
        FinSi
    Destruir request
FinProc




Cualquier sugerencia, o error, comenten.