comment
IRC Chat
play_arrow
Este sitio utiliza cookies propias y de terceros. Si continúa navegando consideramos que acepta el uso de cookies. OK Más Información.

[SRC] I/O Asincrono windows

  • 2 Respuestas
  • 2344 Vistas

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

Desconectado Arkangel

  • *
  • Underc0der
  • Mensajes: 15
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
« en: Junio 20, 2013, 12:10:37 pm »
Hola, les traigo un code para la lectura y escritura en windows asincrona.
Se puede usar para pipes,ficheros,socket, etc
En teoria soporta una gran carga de trabajo al usar IOCP y overlapped.
Los IO completion port permiten crear una cola de solicitudes de I/O a medida que se van completando se pueden ir recuperando con GetQueuedCompletionStatus.
Esto es mas eficiente que crear un hilo por cada solicitud, a partir de un cierto numero de hilos la sobrecarga del cambio de tareas empieza a ser significativa y la memoria requerida para crear esso hilos se dispara.
Con este metodo un pequeño numero de hilos puede atender a una gran cantidad de solicitudes.
Esto es ideal para crear servidores tcp que podran atender a un gran numero  de clientes

Aqui tienen el code:

iodevice.h
Código: C
  1. #ifndef IODEVICE_H
  2. #define IODEVICE_H
  3.  
  4. #include <windows.h>
  5. #include "basicTypes.h"
  6.  
  7. struct IODevice;
  8. typedef void(*ioCompletionCallback)(struct IODevice* io,byte* buff,ulong BytesTransfered,ulong op,ulong status);
  9.  
  10.  
  11. //Op codes for IOCP
  12. #define OP_READ     0
  13. #define OP_WRITE    1
  14. #define OP_EOF      2
  15. #define OP_CLOSE    3
  16.  
  17. #define STATUS_CANCELLED 0xC0000120
  18.  
  19. typedef struct OVERLAPPEDex{
  20.     OVERLAPPED Overlapped;
  21.     int opCode;
  22.     byte* buff;
  23. }OVERLAPPEDex;
  24.  
  25. typedef int (*IODeviceDispatchIoCompletion)(struct IODevice* io,OVERLAPPEDex* Overlapped,ulong BytesTransfered,bool result);
  26. typedef int (*IODeviceWrite)(struct IODevice* io,const byte* buff,ulong nBytes);
  27. typedef int (*IODeviceRead)(struct IODevice* io,byte* buff,ulong maxBuff);
  28. typedef void (*IODeviceCloseHandle)(struct IODevice* io);
  29.  
  30. typedef struct IODevice{
  31.         enum mode{
  32.             m_none = 0,
  33.             m_read = 1,
  34.             m_write = 2,
  35.             m_rw = 3
  36.         }mode;
  37.  
  38.         IODeviceRead read;
  39.         IODeviceWrite write;
  40.         IODeviceDispatchIoCompletion dispatchIoCompletion;
  41.         ioCompletionCallback ioCompletion;
  42.         IODeviceCloseHandle closeHandle;
  43.         ulong error;
  44.         void* context;
  45. }IODevice;
  46. struct IODevice* createIODevice(HANDLE h,ulong mode);
  47. HANDLE IODevice_getHandle(struct IODevice* io);
  48. void closeIODevice(struct IODevice* io);
  49. void freeIODevice(struct IODevice *io);
  50.  
  51. #endif // IODEVICE_H
  52.  

iodevice.c
Código: C
  1. #include "iodevice.h"
  2. #include <stdio.h>
  3.  
  4.  
  5. HANDLE completionPort = null;
  6. void CALLBACK ThreadIoCompletion(int);
  7.  
  8. void IODevice_closeHandle(struct IODevice *io);
  9.  
  10. bool inicializeIOCP(){
  11.     bool result = false;
  12.  
  13.     if(completionPort == null){
  14.         completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0 );
  15.         if(completionPort != null){
  16.             int i;
  17.             for(i = 0;i<8;i++){
  18.                 CreateThread(null,0,(LPTHREAD_START_ROUTINE)&ThreadIoCompletion,(LPVOID)i,0,null);
  19.             }
  20.             result = true;
  21.         }else{
  22.             No tienes permisos para ver links. Registrate o Entra con tu cuenta("Error creating IOCP %d\n", (int)GetLastError());
  23.         }
  24.     }else {
  25.         result = true;
  26.     }
  27.     return result;
  28. }
  29. typedef struct IODevicePrivate{
  30.     struct IODevice device;
  31.     HANDLE hFile;
  32.     int mode;
  33.     OVERLAPPEDex rOverlapped;
  34.     OVERLAPPEDex wOverlapped;
  35. }IODevicePrivate;
  36.  
  37. int IODevice_read(struct IODevice* io,byte* buff,ulong maxBuff){
  38.     ulong NumberOfBytesReated = -1;
  39.     if(io && (((IODevicePrivate*)io)->mode & m_read)){
  40.         ioCompletionCallback callback = null;
  41.         OVERLAPPEDex* Overlapped = &((IODevicePrivate*)io)->rOverlapped;
  42.         ZeroMemory(Overlapped,sizeof(*Overlapped));
  43.         Overlapped->opCode = OP_READ;
  44.         Overlapped->buff = buff;
  45.  
  46.         if(!ReadFile(((IODevicePrivate*)io)->hFile
  47.                            ,buff,maxBuff,&NumberOfBytesReated,(OVERLAPPED*)Overlapped)){
  48.             int error = GetLastError();
  49.             switch (error) {
  50.                 case ERROR_IO_PENDING:
  51.                     // si el modo asincrono no esta activado, esperamos a que complete
  52.                     callback = ((IODevicePrivate*)io)->device.ioCompletion;
  53.                     if(!callback){
  54.                         GetOverlappedResult(((IODevicePrivate*)io)->hFile,
  55.                                                (OVERLAPPED*)Overlapped,&NumberOfBytesReated,true)
  56.                     }
  57.                     break;
  58.                 default:
  59.                     No tienes permisos para ver links. Registrate o Entra con tu cuenta("ReadFile error: %d\n",error);
  60.                     break;
  61.             }
  62.         }
  63.     }
  64.     return NumberOfBytesReated;
  65. }
  66.  
  67. int IODevice_write(struct IODevice* io,const byte* buff,ulong nBytes){
  68.     ulong NumberOfBytesWritten = -1;
  69.     if(io && (((IODevicePrivate*)io)->mode & m_write)){
  70.         ioCompletionCallback callback = null;
  71.         OVERLAPPEDex* Overlapped = &((IODevicePrivate*)io)->wOverlapped;
  72.         Overlapped->opCode = OP_WRITE;
  73.         Overlapped->buff = (byte*)buff;
  74.  
  75.         if(!WriteFile(((IODevicePrivate*)io)->hFile
  76.                             ,buff,nBytes,&NumberOfBytesWritten,(OVERLAPPED*)Overlapped)){
  77.             int error = GetLastError();
  78.             switch (error) {
  79.                 case ERROR_IO_PENDING:
  80.                     // si el modo asincrono no esta activado, esperamos a que complete
  81.                     callback = io->ioCompletion;
  82.                     if(!callback){
  83.                         GetOverlappedResult(((IODevicePrivate*)io)->hFile,
  84.                                                (OVERLAPPED*)Overlapped,&NumberOfBytesWritten,true)
  85.                     }
  86.                     break;
  87.                 default:
  88.                     No tienes permisos para ver links. Registrate o Entra con tu cuenta("WriteFile error: %d\n",error);
  89.                     break;
  90.             }
  91.         }
  92.     }
  93.     return NumberOfBytesWritten;
  94. }
  95. int IODevice_dispatchIoCompletion(IODevicePrivate* io,OVERLAPPEDex* Overlapped,ulong BytesTransfered,bool result){
  96.     if(io){
  97.         byte* buff = null;
  98.         int opCode,errorCode = 0;
  99.         if(Overlapped){
  100.             buff = Overlapped->buff;
  101.             errorCode = Overlapped->Overlapped.Internal;
  102.             opCode = Overlapped->opCode;
  103.  
  104.             if(result && !BytesTransfered && opCode == OP_READ){
  105.                 opCode = OP_EOF;
  106.                 No tienes permisos para ver links. Registrate o Entra con tu cuenta("OP_EOF %u\n",errorCode);
  107.             }
  108.         }else{
  109.             opCode = OP_CLOSE;
  110.         }
  111.  
  112.         switch(opCode){
  113.             case OP_EOF:
  114.             case OP_READ:
  115.             case OP_WRITE:
  116.                 if(io->device.ioCompletion)io->device.ioCompletion((IODevice*)io,buff,
  117.                                                                    BytesTransfered,opCode,
  118.                                                                    errorCode);
  119.                 break;
  120.             case OP_CLOSE:
  121.                 if(io->device.ioCompletion)io->device.ioCompletion((IODevice*)io,buff,
  122.                                                                    BytesTransfered,opCode,
  123.                                                                    errorCode);
  124.                 io->device.closeHandle((IODevice*)io);
  125.                 No tienes permisos para ver links. Registrate o Entra con tu cuenta(io);
  126.             default:
  127.                 ;
  128.         }
  129.     }
  130.     return 0;
  131. }
  132. struct IODevice* createIODevice(HANDLE h,ulong mode){
  133.     IODevicePrivate* ioDevice = null;
  134.     if(inicializeIOCP()){
  135.         ioDevice = No tienes permisos para ver links. Registrate o Entra con tu cuenta(sizeof(IODevicePrivate));
  136.         if(ioDevice){
  137.             ZeroMemory(ioDevice,sizeof(*ioDevice));
  138.  
  139.             ioDevice->mode = mode;
  140.             ioDevice->hFile = h;
  141.             ioDevice->device.read = &IODevice_read;
  142.             ioDevice->device.write = &IODevice_write;
  143.             ioDevice->device.dispatchIoCompletion = (IODeviceDispatchIoCompletion)&IODevice_dispatchIoCompletion;
  144.             ioDevice->device.closeHandle = &IODevice_closeHandle;
  145.  
  146.             CreateIoCompletionPort(h,completionPort,(DWORD)ioDevice,0);
  147.         }
  148.     }
  149.  
  150.     return (struct IODevice*)ioDevice;
  151. }
  152. void CALLBACK ThreadIoCompletion(int lpParam){
  153.     int nThreadNo = lpParam;
  154.  
  155.     OVERLAPPEDex *pOverlapped = NULL;
  156.     IODevicePrivate   *pContext = NULL;
  157.     DWORD            dwBytesTransfered = 0;
  158.  
  159.     bool result = true;
  160.     while (result) {
  161.         result = GetQueuedCompletionStatus(
  162.                     completionPort,
  163.                     &dwBytesTransfered,
  164.                     (LPDWORD)&pContext,
  165.                     (LPOVERLAPPED*)&pOverlapped,
  166.                     INFINITE);
  167.         if (!pContext){
  168.             //Estan pidiendo parar
  169.             break;
  170.         }
  171.         No tienes permisos para ver links. Registrate o Entra con tu cuenta("thread dispatching: %d\n",nThreadNo);
  172.         pContext->device.dispatchIoCompletion((struct IODevice*)pContext,pOverlapped,dwBytesTransfered,result);
  173.     }
  174. }
  175.  
  176.  
  177. void closeIODevice(struct IODevice *io){
  178.     //Cancelamos las operaciones pendientes y enviamos un mensaje a la cosa sin
  179.  
  180.     if(!CancelIo(((IODevicePrivate*)io)->hFile))
  181.         No tienes permisos para ver links. Registrate o Entra con tu cuenta("CancelIo error: %u\n",(uint)GetLastError());
  182.     //Cambiamos el modo a none para que no se pueda llamar mas a read y a write
  183.     ((IODevicePrivate*)io)->mode = m_none;
  184.     PostQueuedCompletionStatus(completionPort,0,(uint)io,null);
  185. }
  186. void IODevice_closeHandle(struct IODevice *io){
  187.     CloseHandle(((IODevicePrivate*)io)->hFile);
  188. }
  189.  
  190. HANDLE IODevice_getHandle(struct IODevice *io){
  191.     return ((IODevicePrivate*)io)->hFile;
  192. }
  193.  
  194.  

Saludos
« Última modificación: Febrero 08, 2014, 05:37:05 pm por Expermicid »

Desconectado Karcrack

  • *
  • Underc0der
  • Mensajes: 87
  • Actividad:
    0%
  • Reputación 0
  • Se siente observado ¬¬'
    • Ver Perfil
« Respuesta #1 en: Junio 20, 2013, 12:55:14 pm »

Buen código ;D Sólo faltaría un ejemplo de uso ::)
I code for $$$.

(PGP ID 0xCC050E77)
ASM, C, C++, VB6... skilled [malware] developer

Desconectado Arkangel

  • *
  • Underc0der
  • Mensajes: 15
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
« Respuesta #2 en: Junio 20, 2013, 02:10:26 pm »
Aqui te oingo unos trozos de un codigo donde lo uso

Código: C
  1.  
  2. //En esta funcion se aceptarian clientes del socket
  3. int Socket_listen(ushort port,AcceptClientsCallback onAcceptClients){
  4. .....
  5. .....
  6. while ((clientSocket = accept(serverSocket,(SOCKADDR*)&clientAddr,&clientAddrSize)) != INVALID_SOCKET) {
  7.                         //Aqui se crea el IODevice a partir del socket
  8.                         IODevice* ioClient = createIODevice((HANDLE)clientSocket,m_rw);
  9.                         if(ioClient){
  10.                             //Luego si hace falta cambiar alguna funcion como la de close, para casos especificos
  11.                             ioClient->closeHandle = &Net_closeSocket;
  12.  
  13.                             onAcceptClients((struct sockaddr*)&clientAddr,ioClient);
  14.                         }else{
  15.                             No tienes permisos para ver links. Registrate o Entra con tu cuenta("createIODevice error\n");
  16.                             closesocket(clientSocket);
  17.                         }
  18.                     }
  19. ...
  20. ...
  21. }
  22.  
  23. void httpClientDispatcher(struct sockaddr* addr,struct IODevice* io){
  24.     //stream_printf(out,"hello\n");
  25.     Http* newHttp = (Http*)No tienes permisos para ver links. Registrate o Entra con tu cuenta(sizeof(*newHttp));
  26.     ZeroMemory(newHttp,sizeof(*newHttp));
  27.     newHttp->maxRead = 1024;
  28.     newHttp->readBuff = No tienes permisos para ver links. Registrate o Entra con tu cuenta(newHttp->maxRead);
  29.  
  30.     //Aqui se pone la funcion que atendera las notificaciones de datos leidos, escritos, fin de fichero y close
  31.     io->context = newHttp;
  32.     io->ioCompletion = &http_ioCompletion;
  33.  
  34.     /*
  35.      *Aqui se empieza una solicitud de lectura y otra se escritura, pueden estar pendientes las 2 a la vez
  36.      * Para detectar el fin de fichero hay que intentar leer
  37.      */
  38.     io->read(io,newHttp->readBuff,newHttp->maxRead);
  39.  
  40.     io->write(io,(const byte*)"hola\n",sizeof("hola\n"));
  41. }
  42.  
  43. void http_ioCompletion(struct IODevice* io,byte* buff,ulong BytesTransfered,ulong op,ulong status){
  44.     Http* http = (Http*)io->context;
  45.  
  46.     //Aqui se manejan las diferentes notificaciones
  47.     switch (op) {
  48.         case OP_WRITE:
  49.             No tienes permisos para ver links. Registrate o Entra con tu cuenta("http BytesWrited: %u, data: %s\n",(uint)BytesTransfered,buff);
  50.             break;
  51.         case OP_READ:
  52.             if(status != STATUS_CANCELLED && status != ERROR_PROCESS_ABORTED){
  53.                 bool continueRead = true;
  54.                
  55.                 No tienes permisos para ver links. Registrate o Entra con tu cuenta("http BytesReated: %s\n",buff);
  56.                 ZeroMemory(http->readBuff,http->maxRead);
  57.  
  58.                 if(No tienes permisos para ver links. Registrate o Entra con tu cuenta("bye",buff)==0){
  59.                         closeIODevice(io);
  60.                         continueRead = false;
  61.                 }
  62.  
  63.  
  64.                 if(continueRead)io->read(io,http->readBuff,http->maxRead);
  65.  
  66.             }
  67.             break;
  68.         case OP_EOF:
  69.             closeIODevice(io);
  70.             break;
  71.         case OP_CLOSE:
  72.             No tienes permisos para ver links. Registrate o Entra con tu cuenta("Cliente desconectado\n");
  73.             break;
  74.         default:
  75.             break;
  76.     }
  77. }
  78.  
  79.  

 

¿Te gustó el post? COMPARTILO!



Apagado-Shutdown Function(Windows)

Iniciado por Jhonjhon_123

Respuestas: 3
Vistas: 2215
Último mensaje Noviembre 13, 2012, 03:33:22 pm
por daryo