Advertisement
Guest User

Untitled

a guest
Apr 7th, 2011
538
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.41 KB | None | 0 0
  1. /* gcc -g -Wall -o server.exe server5.c */
  2.  
  3. #include <stdio.h>
  4.  
  5. #include <windows.h>
  6. #include <process.h>
  7.  
  8.  
  9. #define BUFSIZE 512
  10.  
  11. HANDLE objects[2];
  12.  
  13. typedef struct
  14. {
  15.   HANDLE pipe;
  16.   HANDLE event_exit;
  17.   OVERLAPPED ol;
  18.   OVERLAPPED ol_read;
  19.   DWORD read_count;
  20.   int exit_thread;
  21.  
  22.   HANDLE iocp_read;
  23.  
  24.   /* in normal struct */
  25.   void *data;
  26.   int size;
  27. } Server;
  28.  
  29. void print_last_error(const char *fct);
  30.  
  31. static void
  32. _svr_data_append(Server *svr, void *data, size_t size)
  33. {
  34.   if (!svr->data)
  35.     {
  36.       svr->data = malloc(size);
  37.       if (!svr->data)
  38.         return;
  39.       memcpy(svr->data, data, size);
  40.       svr->size = size;
  41.     }
  42.   else
  43.     {
  44.       void *tmp;
  45.       tmp = realloc(svr->data, svr->size + size);
  46.       if (tmp)
  47.         {
  48.           svr->data = tmp;
  49.           memcpy(svr->data + svr->size, data, size);
  50.           svr->size += size;
  51.         }
  52.     }
  53.  
  54.   {
  55.     char *buf;
  56.     buf = malloc(svr->size + 1);
  57.     memcpy(buf, svr->data, svr->size);
  58.     buf[svr->size] = 0;
  59.     printf("msg (%d -> %02d) : %s\n", (int)size, (int)svr->size, buf);
  60.     free(buf);
  61.   }
  62. }
  63.  
  64. static unsigned int __stdcall
  65. _read_data_cb(void *data)
  66. {
  67. #define READ_BUFSIZE 5
  68.   char buf[READ_BUFSIZE];
  69.   Server *svr;
  70.   DWORD nbr_bytes = 0;
  71.   BOOL res;
  72.   BOOL pending = FALSE;
  73.  
  74.   ULONG_PTR key;
  75.   LPOVERLAPPED lpol;
  76.  
  77.   svr = (Server *)data;
  78.  
  79.   while (!svr->exit_thread)
  80.     {
  81.       res = ReadFile(svr->pipe, buf, sizeof(buf),
  82.                      &nbr_bytes, &svr->ol_read);
  83.       if (res)
  84.         {
  85.  
  86.           printf("ReadFile 1\n");
  87.           _svr_data_append(svr, buf, nbr_bytes);
  88.           do {
  89.             res = ReadFile(svr->pipe, buf, sizeof(buf),
  90.                            &nbr_bytes, &svr->ol_read);
  91.             if (res)
  92.               {
  93.                 printf("ReadFile 2\n");
  94.                 _svr_data_append(svr, buf, nbr_bytes);
  95.               }
  96.             else
  97.               {
  98.                 DWORD err = GetLastError();
  99.                 if (err == ERROR_IO_PENDING)
  100.                   {
  101.                     printf("ReadFile2: ERROR_IO_PENDING\n");
  102.                     pending = TRUE;
  103.                   }
  104.                 else if (err == ERROR_SUCCESS)
  105.                   {
  106.                     printf(" * success\n");
  107.                     continue;
  108.                   }
  109.                 else if (err == ERROR_BROKEN_PIPE)
  110.                   {
  111.                     printf(" * broken pipe\n");
  112.                     SetEvent(svr->event_exit);
  113.                   }
  114.                 else
  115.                   {
  116.                     printf(" * unexpected error %ld\n", err);
  117.                     SetEvent(svr->event_exit);
  118.                   }
  119.                 break;
  120.               }
  121.           } while (1);
  122.         }
  123.       else
  124.         {
  125.           DWORD err = GetLastError();
  126.           if (err == ERROR_IO_PENDING)
  127.             {
  128.               printf("ReadFile1: ERROR_IO_PENDING\n");
  129.               pending = TRUE;
  130.             }
  131.           else if (err == ERROR_SUCCESS)
  132.             {
  133.               printf(" * success\n");
  134.               continue;
  135.             }
  136.           else if (err == ERROR_BROKEN_PIPE)
  137.             {
  138.               printf(" * broken pipe\n");
  139.               SetEvent(svr->event_exit);
  140.             }
  141.           else
  142.             {
  143.               printf(" * unexpected error %ld\n", err);
  144.               SetEvent(svr->event_exit);
  145.             }
  146.         }
  147.  
  148.       if (pending)
  149.         {
  150.           res = GetQueuedCompletionStatus(svr->iocp_read, &nbr_bytes, &key, &lpol, INFINITE);
  151.           printf("GQCIOS %d %d %p\n", (int)nbr_bytes, (int)key, lpol);
  152.           if (res && lpol)
  153.             {
  154.               res = ReadFile(svr->pipe, buf, sizeof(buf),
  155.                              &nbr_bytes, &svr->ol_read);
  156.               if (res)
  157.                 {
  158.                   pending = FALSE;
  159.                   printf("ReadFile 3\n");
  160.                   _svr_data_append(svr, buf, nbr_bytes);
  161.                 }
  162.               else
  163.                 {
  164.                   DWORD err = GetLastError();
  165.                 if (err == ERROR_IO_PENDING)
  166.                   {
  167.                     printf("ReadFile3: ERROR_IO_PENDING\n");
  168.                   }
  169.                 }
  170.             }
  171.           else
  172.             {
  173.               DWORD err = GetLastError();
  174.               print_last_error("GetQueuedCompletionStatus");
  175.               if (err == ERROR_IO_PENDING)
  176.                 {
  177.                   pending = TRUE;
  178.                 }
  179.             }
  180.         }
  181.     }
  182.  
  183.   printf("ending thread...\n");
  184.  
  185.   _endthreadex(0);
  186.   return 0;
  187. }
  188.  
  189. void print_last_error(const char *fct)
  190. {
  191.   char *buf;
  192.   DWORD dw = GetLastError();
  193.  
  194.   FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  195.                 FORMAT_MESSAGE_FROM_SYSTEM |
  196.                 FORMAT_MESSAGE_IGNORE_INSERTS,
  197.                 NULL,
  198.                 dw,
  199.                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  200.                 (LPTSTR) &buf,
  201.                 0, NULL );
  202.  
  203.     // Display the error message and exit the process
  204.  
  205.   printf("%s failed with error %ld: %s\n", fct, dw, buf);
  206.   LocalFree(buf);
  207. }
  208.  
  209. Server *
  210. server_new(const char *name)
  211. {
  212.   char buf[256];
  213.   Server *svr;
  214.   HANDLE event;
  215.   BOOL res;
  216.  
  217.   HANDLE iocp;
  218.   ULONG_PTR key = 0xff;
  219.  
  220.   if (!name)
  221.     return NULL;
  222.  
  223.   svr = (Server *)calloc(1,sizeof(Server));
  224.   if (!svr)
  225.     return NULL;
  226.  
  227.   snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", name);
  228.  
  229.   /*
  230.    * Asynchronuous
  231.    * block mode
  232.    */
  233.   svr->pipe = CreateNamedPipe(buf,
  234.                               PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
  235.                               PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
  236.                               PIPE_UNLIMITED_INSTANCES,
  237.                               512, 512, 5000, NULL);
  238.   if (!svr->pipe)
  239.     {
  240.       print_last_error("CreateNamedPipe");
  241.       goto free_svr;
  242.     }
  243.  
  244.   /*
  245.    * ConnectNamedPipe() event
  246.    * Manual reset
  247.    * Initial state : non signaled
  248.    */
  249.   event = CreateEvent(NULL, TRUE, FALSE, NULL);
  250.   if (!event)
  251.     {
  252.       print_last_error("CreateEvent");
  253.       goto close_pipe;
  254.     }
  255.  
  256.   memset(&svr->ol, 0, sizeof(svr->ol));
  257.   svr->ol.hEvent = event;
  258.   objects[0] = svr->ol.hEvent;
  259.  
  260.   res = ConnectNamedPipe(svr->pipe, &svr->ol);
  261.   if (res)
  262.     {
  263.       print_last_error("ConnectNamedPipe");
  264.       goto close_event;
  265.     }
  266.   else
  267.     {
  268.       DWORD err = GetLastError();
  269.  
  270.       if (err == ERROR_PIPE_CONNECTED)
  271.         {
  272.           SetEvent(svr->ol.hEvent);
  273.           printf("client connected\n");
  274.         }
  275.       else if (err != ERROR_IO_PENDING)
  276.         {
  277.           print_last_error("ConnectNamedPipe");
  278.           goto close_event;
  279.         }
  280.       /* else, we have ERROR_IO_PENDING, so a connection link is pending */
  281.     }
  282.  
  283.   /*
  284.    * Exit event
  285.    * Manual reset
  286.    * Initial state : non signaled
  287.    */
  288.   event = CreateEvent(NULL, TRUE, FALSE, NULL);
  289.   if (!event)
  290.     {
  291.       print_last_error("CreateEvent (event exit)");
  292.       goto close_event;
  293.     }
  294.   svr->event_exit = event;
  295.   objects[1] = svr->event_exit;
  296.  
  297.   /*
  298.    * ReadFile() event
  299.    * Manual reset
  300.    * Initial state : non signaled
  301.    */
  302.   event = CreateEvent(NULL, TRUE, FALSE, NULL);
  303.   if (!event)
  304.     {
  305.       print_last_error("CreateEvent (event exit)");
  306.       goto close_event_exit;
  307.     }
  308.  
  309.   memset(&svr->ol_read, 0, sizeof(svr->ol_read));
  310.   svr->ol_read.hEvent = event;
  311.  
  312.   iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
  313.   if (!iocp)
  314.     {
  315.       print_last_error("CreateIoCompletionPort");
  316.       goto close_event_exit;
  317.     }
  318.  
  319.   svr->iocp_read = CreateIoCompletionPort(svr->pipe, iocp, key, 1);
  320.   if (!svr->iocp_read)
  321.     {
  322.       print_last_error("CreateIoCompletionPort");
  323.       goto close_event_exit;
  324.     }
  325.  
  326.   return svr;
  327.  
  328.  close_event_exit:
  329.   CloseHandle(svr->event_exit);
  330.  close_event:
  331.   CloseHandle(event);
  332.  close_pipe:
  333.   CloseHandle(svr->pipe);
  334.  free_svr:
  335.   free(svr);
  336.  
  337.   return NULL;
  338. }
  339.  
  340. void
  341. server_del(Server *svr)
  342. {
  343.   if (!svr)
  344.     return;
  345.  
  346.   CloseHandle(svr->event_exit);
  347.   if (!FlushFileBuffers(svr->pipe))
  348.     {
  349.       print_last_error("FlushFileBuffers");
  350.     }
  351.   if (!DisconnectNamedPipe(svr->pipe))
  352.     {
  353.       print_last_error("DisconnectNamedPipe");
  354.     }
  355.   CloseHandle(svr->ol.hEvent);
  356.   CloseHandle(svr->pipe);
  357.   free(svr);
  358. }
  359.  
  360. int main()
  361. {
  362.   Server *svr;
  363.   DWORD ret;
  364.   DWORD nbr_bytes;
  365.   BOOL res;
  366.  
  367.   svr = server_new("toto");
  368.   if (!svr)
  369.     return -1;
  370.  
  371.   printf("waiting for client...\n");
  372.  
  373.   while (1)
  374.     {
  375.       ret = WaitForMultipleObjects(2, objects, FALSE, INFINITE);
  376.       if (ret == WAIT_FAILED)
  377.         {
  378.           print_last_error("WaitForMultipleObjects");
  379.           goto beach;
  380.         }
  381.       printf("WaitForMultipleObjects : %ld\n", ret);
  382.  
  383.       if (ret == WAIT_OBJECT_0)
  384.         {
  385.           ResetEvent(svr->ol.hEvent);
  386.  
  387.           res = GetOverlappedResult(svr->pipe, &svr->ol,
  388.                                     &nbr_bytes, FALSE);
  389.           if (!res)
  390.             {
  391.               print_last_error("GetOverlappedResult");
  392.  
  393.               if (!DisconnectNamedPipe(svr->pipe))
  394.                 {
  395.                   print_last_error("DisconnectNamedPipe");
  396.                   goto beach;
  397.                 }
  398.  
  399.               res = ConnectNamedPipe(svr->pipe, &svr->ol);
  400.               if (res)
  401.                 {
  402.                   print_last_error("ConnectNamedPipe");
  403.                   goto beach;
  404.                 }
  405.               else
  406.                 {
  407.                   DWORD err = GetLastError();
  408.  
  409.                   if (err == ERROR_PIPE_CONNECTED)
  410.                     {
  411.                       SetEvent(svr->ol.hEvent);
  412.                     }
  413.                   else if (err != ERROR_IO_PENDING)
  414.                     {
  415.                       print_last_error("ConnectNamedPipe");
  416.                       goto beach;
  417.                     }
  418.                   /* else, we have ERROR_IO_PENDING, so a connection link is pending */
  419.                 }
  420.             }
  421.           else
  422.             {
  423.               printf("client connected (%d)\n", res);
  424.  
  425.               /* read pipe */
  426.               _beginthreadex(NULL, 0, _read_data_cb, svr, 0, NULL);
  427.             }
  428.         }
  429.       if (ret == (WAIT_OBJECT_0 + 1))
  430.         {
  431.           printf("client connection closed\n");
  432.           svr->exit_thread = 1;
  433.           goto beach;
  434.         }
  435.       if (ret == (WAIT_OBJECT_0 + 2))
  436.         {
  437.         }
  438.     }
  439.  
  440.  beach:
  441.   server_del(svr);
  442.  
  443.   return 0;
  444. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement