[Modulo] Sockets Async 1.3b (21/06/2016)
#1
Sockets Async 1.3b


Descripción:
A diferencia de los demás modulos, este utiliza sockets asincronicos (non-blocking), eso significa que no hay peligro que el servidor se tilde al esperar una respuesta.

Mejoras:
- Sin bloqueo (asincronico)
- Identificación de sockets controlada (los demás modulos al pasar un socket invalido te crashean el servidor...)
- Forwards (sin tener que estar con un task/think en los plugins)
- Soporte para múltiples clientes TCP (a cada cliente se le asigna un socket nuevo)
- Soporte para UDP (sendto y recvfrom)


Include:
Código PHP:
enum SOCKET: {}


enum {
    
SOCK_TYPE_UDP=0,
    
SOCK_TYPE_TCP,
    
SOCK_TYPE_CHILD // Son los nuevos sockets que se crean al aceptar una conexion TCP
}


native SOCKET:socket_create(typecustomID)

native socket_lasterror()
native socket_getip(const hostname[], ip[], len)

native socket_close(SOCKET:socket)
native socket_bind(SOCKET:socket, const local_ip[]=""local_port)

native socket_get_custom(SOCKET:socket)
native socket_set_custom(SOCKET:socketcustomID)

// TCP
native socket_connect(SOCKET:socket, const hostname[], port)
native socket_send(SOCKET:socket, const data[], sendsize=0)
native socket_recv(SOCKET:socketdata[], maxlen)

// UDP
native socket_sendto(SOCKET:socket, const ip[], port, const data[], sendsize=0)
native socket_recvfrom(SOCKET:socketdata[], maxlenip[], len, &port)

forward fw_sockConnected(SOCKET:socketcustomID)
forward fw_sockClosed(SOCKET:socketcustomIDerror)
forward fw_sockAccepted(SOCKET:socketcustomIDSOCKET:cl_sock, const cl_ip[], cl_port)
forward fw_sockReadable(SOCKET:socketcustomIDtype)
forward fw_sockWritable(SOCKET:socketcustomIDtype

ChangeLog:
Código:
1.3b
- Fix bug socket_recvfrom

1.3
- Fix bugs win/linux
- Code optimice

1.2
- Fix bugs linux

1.1b
- Fix bugs win/linux

1.1:
- Fix error en linux Centos
- Fix crash al usar socket_close y hookear fw_sockClosed
- Add socket_lasterror()
- Add socket_getip(...)

1.0:
- Codigo corregido para compilar en linux

1.0Beta:
- Publicación

Github: (desactualizado)
Github / Destro- / amxx / sockets_async


Archivos adjuntos
.sma   Descargar AMXX / sockets_aync_test.sma (Tamaño: 6.81 KB / Descargas: 425)
.inc   sockets_async.inc (Tamaño: 1.34 KB / Descargas: 427)
.rar   source.rar (Tamaño: 47.54 KB / Descargas: 180)
.rar   bin.rar (Tamaño: 51.09 KB / Descargas: 344)
Responder
#2
Gracias por el aporte Gran sonrisa
[Imagen: b_350_20_323957_202743_f19a15_111111.png]

Estudia siempre; el tiempo es oro, lo material se puede recuperar pero el tiempo no se puede recuperar.
(02/10/2016, 05:05 PM)meTaLiCroSS escribió: Siempre me gusta ayudar cuando alguien esta interesado realmente en ver que esta programando.
(08/08/2019, 05:32 PM)meTaLiCroSS escribió: grax x el dato cr4ck


Mis aportes

PLUGINS
MAPAS
Menú LANG [SF] Sistema de Frags
Say System (Admin Prefix)
Responder
#3
SOCK_TYPE_CHILD sos un Mangieri terrible.

Después le pego una miradita.
Pacman rip :'v
Responder
#4
Subido el modulo para linux (sin probar)
Responder
#5
a estas con todas destro , jaja exelenteee sirve sirvee
[Imagen: tumblr_mt8w6d7yz11rn3500o1_400.gif]
Responder
#6
Update 1.1

Me hizo renegar como negro para compilarlo en linux y que no pida versiones de GLIBC modernas
Todo sea por las Selfies en el CS Crab
Responder
#7
Che destro, tu modulo me carga todo, pero cuando pongo el plugin con el stock no importa si el plugin esta default la cosa es que me aparece unknown, esta todo bien colocado.

¿Alguna solución?
Responder
#8
Hola ¿alguien me puede decir como se instala?

solamente reemplazo el sockets que tengo por este?
Responder
#9
Actualizado v1.3b (win/linux)

Cita:Corregido un error en la native socket_recvfrom que devolvía siempre 0 como puerto

Responder
#10
A que se debe este log: ?
Me suele aparecer en los logs..

Código:
[SOCKET] Sockets-A: debug4: error:[0][11]
Believe, be yourself and don't hold on to just one dream ❤

Responder
#11
Habria alguna forma de obtener datos de un servidor como en el sockets viejo, para hacer un redirect con este module
Osea obtener jugadores, mapa, max de jugadores, y eso.
Responder
#12
(24/07/2016, 03:16 PM)Exertency escribió: Habria alguna forma de obtener datos de un servidor como en el sockets viejo, para hacer un redirect con este module
Osea obtener jugadores, mapa, max de jugadores, y eso.

Si, tenés que adaptar ciertas funciones que tiene el redirect original en cuanto a obtener los datos recibidos de los servidores. https://forums.alliedmods.net/showthread.php?t=29886

Pero antes que nada, tendrías que saber algo básico de sockets y luego poder entender casi perfectamente como funciona el módulo de Destro para poder lograr lo que quieres. Tenés que hacer un plugin y tratar de conectarte con algo y ver como funciona, es prueba y error.
Believe, be yourself and don't hold on to just one dream ❤

Responder
#13
Cómo puedo hacer para enviar una screenshot al servidor web usando sockets? La imagen es muy "pesada" (generalmente alrededor de 30kb) para poder ser almacenada en una variable/string, por lo que me sube la imagen recortada, apenas solo un 10% aproximadamente del archivo.
Responder
#14
pasa lo que tenes y le doy una mirada

también podes darle una mirada al modulo de curl
la api curl esta exportada en muchos lenguajes, seguro encontrás muchos ejemplos que podes adaptar
Responder
#15
Tengo esto:

Código PHP:
#include <amxmodx>
#include <sockets_async>

new const upload_file[] = "A3F0CC91.5_1483514216.jpg"
new const upload_host[] = "www.miweb.com"
new const upload_script[] = "/upload.php"

new const download_savefile[] = "addons/amxmodx/logs/amxx-es.htm"
new const download_host[] = "www.amxmodx-es.com"
new const download_script[] = "/index.php"

new const send_udp_ip[] = "190.0.xxx.xxx"
const send_udp_port     27020

const listen_udp_port     27015
const listen_tcp_port     8888


new const log_file[] = "sockets_async.log"


enum {
    
SOCKET:SOCK_SEND_UDP,
    
SOCKET:SOCK_LISTEN_UDP,
    
SOCKET:SOCK_LISTEN_TCP,
    
SOCKET:SOCK_UPLOAD,
    
SOCKET:SOCK_DOWNLOAD,
    
SOCK_CLIENT
}
new const 
sockets_name[][] = { "SEND_UDP""LISTEN_UDP""LISTEN_TCP""UPLOAD""DOWNLOAD""CLIENT" }

new 
SOCKET:g_sock[SOCK_CLIENT]
new 
g_write_download

public plugin_init()
{
    
register_plugin("Test: Sockets Async""1.0""Destro")
    

    
set_task(4.0"create_sokets")
}

public 
create_sokets()
{
    new 
result
    
    
    
/*===  CREATE  ============================================================================*/
    
g_sock[SOCK_UPLOAD]    = socket_create(SOCK_TYPE_TCPSOCK_UPLOAD)
    
g_sock[SOCK_DOWNLOAD]    = socket_create(SOCK_TYPE_TCPSOCK_DOWNLOAD)
    
g_sock[SOCK_LISTEN_TCP]    = socket_create(SOCK_TYPE_TCPSOCK_LISTEN_TCP)
    
g_sock[SOCK_LISTEN_UDP] = socket_create(SOCK_TYPE_UDPSOCK_LISTEN_UDP)
    
g_sock[SOCK_SEND_UDP]     = socket_create(SOCK_TYPE_UDPSOCK_SEND_UDP)
    
    for(new 
typetype SOCK_CLIENTtype++)
    {
        if(!
g_sock[type])
        {
            
log_to_file(log_file"*ERROR [%s]: Failed to create socket"sockets_name[type])
            return
        }
    }
    
    
log_to_file(log_file"Create the sockets successful.")
    
/******************************************************************************************/
    
    
    
    /*===  CONNECT  ===========================================================================*/
    
result socket_connect(g_sock[SOCK_UPLOAD], upload_host80)
    
check_connect_error(resultSOCK_UPLOAD)
    
    
result socket_connect(g_sock[SOCK_DOWNLOAD], download_host80)
    
check_connect_error(resultSOCK_DOWNLOAD)
    
/******************************************************************************************/
    
    
    
    /*===  LISTEN  ===========================================================================*/
    
result socket_bind(g_sock[SOCK_LISTEN_TCP], ""listen_tcp_port)
    
check_listen_error(resultSOCK_LISTEN_TCP)
    
    
result socket_bind(g_sock[SOCK_LISTEN_UDP], ""listen_udp_port)
    
check_listen_error(resultSOCK_LISTEN_UDP)
    
/******************************************************************************************/
    
    
    
    /*=== UDP SEND ===========================================================================*/
    
socket_sendto(g_sock[SOCK_SEND_UDP], send_udp_ipsend_udp_port"ecoooooooooooo")
}

check_connect_error(resulttype)
{
    if(
result 0) return
    
    if(
result == 0)
        
log_to_file(log_file"*ERROR [%s]: Failed to connect"sockets_name[type])
    else
        
log_to_file(log_file"*ERROR [%s]: Invalid Hostname/IP."sockets_name[type])
}

check_listen_error(resulttype)
{
    if(
result == 0)
    {
        
log_to_file(log_file"*ERROR [%s]: Failed to bind"sockets_name[type])
    }
}


/*===  FORWARS  ================================================================================*/
public fw_sockConnected(SOCKET:socketcustomID)
{
    
log_to_file(log_file"*[%s]: Connection successful."sockets_name[customID])

    switch(
customID)
    {
        case 
SOCK_UPLOAD:
        {
            new 
fp fopen(upload_file"rb")
            if(!
fp)
            {
                
log_to_file(log_file"*ERROR [%s]: Coulds not open upload File [%s]"sockets_name[customID], upload_file)
                return
            }    
        
            new 
size file_size(upload_file0);

            new 
buff[2000], data[1700], packet_sizelen
        
            len 
copy(datacharsmax(data),
            
"--642865735weasdasdwe4285675865^r^nContent-Disposition: form-data; name=^"file^"; filename=^"2_7BE95034.8_1483504390.jpg^"^r^n^r^n")
        
            
len += fread_blocks(fpdata[len], charsmax(data) - len 50BLOCK_CHAR)
            
len += copy(data[len], charsmax(data) - len"^r^n--642865735weasdasdwe4285675865--^r^n")
        
        
            
packet_size formatex(buffcharsmax(buff),
            
"POST %s HTTP/1.1^nHost: %s^nContent-Type: multipart/form-data; boundary=642865735weasdasdwe4285675865^r^nContent-Length: %d^r^n^r^n",
            
upload_scriptupload_hostlen)
        
            
memcpy(datalenbuff[packet_size], charsmax(buff))
            
copy(buff[packet_size], charsmax(buff) - packet_sizedata)
        
            
packet_size += len

            len 
socket_send(socketbuffpacket_size)
            
//server_print("%s", packet_size)    
            
log_to_file(log_file"*[%s]: Send Packet: %d/%d"sockets_name[customID], lenpacket_size)
            
log_to_file("buff.txt","%s",buff)

        }
        case 
SOCK_DOWNLOAD:
        {
            new 
data[256]
            
            
formatex(datacharsmax(data),
            
"GET %s HTTP/1.1^r^nHost: %s^r^n^r^n",
            
download_scriptdownload_host)
    
            new 
len socket_send(socketdata)
            
log_to_file(log_file"*[%s]: Send Packet: %d/%d"sockets_name[customID], lenstrlen(data))

            
g_write_download fopen(download_savefile"wb")
        }
    }
}

public 
fw_sockClosed(SOCKET:socketcustomIDerror)
{
    
log_to_file(log_file"*[%s]: Connection closed, error num(%d)"sockets_name[customID], error)
    

    if(
customID == SOCK_DOWNLOAD)
    {
        
fclose(g_write_download)
    }
}

public 
fw_sockReadable(SOCKET:socketcustomIDtype)
{
    
log_to_file(log_file"*[%s]: Ready to read data - type:(%d)"sockets_name[customID], type)
    
    new 
data[2048], len
    
    
if(type == SOCK_TYPE_UDP)
    {
        new 
ip[20], port
        
        
do {
            
len socket_recvfrom(socketdatacharsmax(data), ipcharsmax(ip), port)
            if(
len <= 0) break

            
log_to_file(log_file"*[%s]: Recv: size:(%d) - strlen(%d) - packet:[%s]",
            
sockets_name[customID], lenstrlen(data), data)
        
        } while(
len == charsmax(data))
        
    }
    else {
        do {
            
len socket_recv(socketdatacharsmax(data))
        
            if(
len <= 0)
            {
                if(
len == -1)
                    
log_to_file(log_file"*ERROR [%s]: Recv: error"sockets_name[customID])
                else {
                    
log_to_file(log_file"*ERROR [%s]: Recv: No data: Close socket"sockets_name[customID])
                    
socket_close(socket)
                }
                break
            }

            if(
customID == SOCK_DOWNLOAD)
            {
                
log_to_file(log_file"*[%s]: Recv: size:(%d) - strlen(%d)",
                
sockets_name[customID], lenstrlen(data))
                
                
fwrite_blocks(g_write_downloaddatalenBLOCK_BYTE)
            }
            else {
                
log_to_file(log_file"*[%s]: Recv: size:(%d) - strlen(%d) - packet:[%s]",
                
sockets_name[customID], lenstrlen(data), data)
            }
        
        } while(
len == charsmax(data))
    }
}

public 
fw_sockAccepted(SOCKET:socketcustomIDSOCKET:cl_sock, const cl_ip[], cl_port)
{
    
log_to_file(log_file,
    
"*[%s]: Accepted: client IP:[%s] - Port:(%d) - newsocket:(%d)",
    
sockets_name[customID], cl_ipcl_portcl_sock)
    
    
socket_set_custom(cl_sockSOCK_CLIENT)
}

memcpy(const input[], sizeoutput[], maxsize)
{
    for(new 
isize && maxsizei++ )
    {
        
output[i] = input[i]
    }


Básicamente lo que hice acá fue tratar de subir una imagen .jpg de una screen que previamente fue tomada. Modificando la línea 130, la extensión de buff y data hace que se suba más o menos contenido de la imagen.

Una vez que solucione esto, ya estaría empezando a unirlo con el sXe Events que posteaste (https://amxmodx-es.com/Thread-API-sXe-In...vents-1-03 ).
Responder
#16
Código PHP:
new const START_FORMDATA[]    = "--642865735weasdasdwe4285675865^r^nContent-Disposition: form-data; name=^"file^"; filename=^"temp^"^r^n^r^n"
new const END_FORMDATA[]     = "^r^n--642865735weasdasdwe4285675865--^r^n"

new const UPLOAD_HOST[]        = "localhost"
new const UPLOAD_SCRIPT[]     = "/screenshot/upload_screen.php"


new SOCKET:g_socketg_fopeng_hostip[16]
new 
g_upFilename[64], g_upInfo[168], g_upSendBytes

public plugin_init()
{
    
socket_getip(UPLOAD_HOSTg_hostip15)
}


public 
TEST___upload()
{
    
formatex(g_upFilenamecharsmax(g_upFilename), "fotito/A3F0CC91.5_1483514216.jpg")

    
formatex(g_upInfocharsmax(g_upInfo), "datos=%s""datos que se enviaran por la url (metodo GET)")
    
    
g_upSendBytes 0
    set_task
(10.0"task_timeout"TASK_TIMEOUT)
    
    
g_socket socket_create(SOCK_TYPE_TCP0)
    if(
socket_connect(g_socketg_hostip80) <= 0)
    {
        
log_to_file(log_file"Error al crear el socket: (%d) (%d)"g_socketsocket_lasterror())
        
finish_upload()
    }
}

public 
task_timeout()
{
    
finish_upload()
}

finish_upload()
{
    if(
g_socket)
    {
        new  
SOCKET:sock g_socket // Fix Bug fw_sockClosed
        
g_socket SOCKET:0
    
        socket_close
(sock)
    }
    
    if(
g_fopen)
    {
        
fclose(g_fopen)
        
g_fopen 0
    
}
    
    
remove_task(TASK_TIMEOUT)
    
set_task(1.0"check_upload")
}

/*===  FORWARS  ================================================================================*/
public fw_sockConnected(SOCKET:socketcustomID)
{
    if(
g_socket != socket)
        return
        
    
g_fopen fopen(g_upFilename"rb")
    if(!
g_fopen)
    {
        
log_to_file(log_file"Error al abrir el archivo: [%s]"g_upFilename)
        
finish_upload()
        return
    }    

    new 
buff[512], data_sizepacket_size
    
    fseek
(g_fopen0SEEK_END)
    
data_size ftell(g_fopen)
    
fseek(g_fopen0SEEK_SET)
    
data_size += (charsmax(START_FORMDATA) + charsmax(END_FORMDATA))

    
packet_size formatex(buffcharsmax(buff),
    
"POST %s?%s HTTP/1.1^nHost: %s^nContent-Type: multipart/form-data; boundary=642865735weasdasdwe4285675865^r^nContent-Length: %d^r^n^r^n",
    
UPLOAD_SCRIPTg_upInfoUPLOAD_HOSTdata_size)
    
    
add(buffcharsmax(buff), START_FORMDATA)
    
packet_size += charsmax(START_FORMDATA)
    
    if(
socket_send(socketbuffpacket_size) <= 0)
    {
        
log_to_file(log_file"Error al iniciar la trasnferencia del archivo: (%d)"socket_lasterror())
        
finish_upload()
        return
    }

    
send_file()
}

send_file()
{
    new 
buff[2048], read_sizesend_size
    
    
if(g_fopen)
    {
        
fseek(g_fopeng_upSendBytesSEEK_SET)
    
        do {
            
read_size fread_blocks(g_fopenbuffcharsmax(buff), BLOCK_CHAR)
            
send_size socket_send(g_socketbuffread_size)
        
            if(
send_size == 0)
                return
                
            if(
send_size == -1)
            {
                
log_to_file(log_file"Error al trasnferir el archivo: (%d)"socket_lasterror())
                
finish_upload()
                return
            }
            
            
g_upSendBytes += send_size
        
        
} while(read_size == charsmax(buff))
        
        
fclose(g_fopen)
        
g_fopen 0
    
}
    
    
send_size socket_send(g_socketEND_FORMDATA)
    if(
send_size == 0)
        return

    if(
send_size == -1)
    {
        
log_to_file(log_file"Error al finalizar la trasnferencia del archivo: (%d)"socket_lasterror())
        
finish_upload()
        return
    }
}

public 
fw_sockClosed(SOCKET:socketcustomIDerror)
{
    if(
g_socket != socket)
        return
        
    
g_socket SOCKET:0
    log_to_file
(log_file"sockClosed: (%d) (%d)"socket_lasterror(), error)
    
finish_upload()
}

public 
fw_sockWritable(SOCKET:socketcustomIDtype)
{
    if(
g_socket != socket)
        return
        
    
send_file()


en resumen es esto lo que usaba para subir las screens, si algún día me dan ganas capaz que lo cambie a cURL
Responder
#17
Me funcionó de maravilla, mil gracias!
Responder
#18
socket_id y socket_num: https://amxmodx-es.com/Thread-Desvirtue-...#pid186026
socket_handshake y socket_mask: https://amxmodx-es.com/Thread-Desvirtue-...#pid186036
edit 2: para usar _handshake -> crypto_socket.inc https://puu.sh/BeO4e/6cfc55a2c7.inc (tiene el sha1 de Destro pero lo modifiqué y su mismo base64 encode).

Muy útil para cuando quieran manejar websocket, otro día veo si armo el _unmask.

edit 3: data > 4kb = crash? https://amxmodx-es.com/Thread-Desvirtue-...#pid186096

edit: si en el título pones la versión y fecha, después cuando cambies algo, los enlaces anteriores dejan de funcionar.
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)