Advertisement
Guest User

Untitled

a guest
Dec 25th, 2016
375
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.45 KB | None | 0 0
  1. /* gcc -g -Wall -o server.exe server3.c */
  2.  
  3. #include <stdio.h>
  4.  
  5. #include <windows.h>
  6. #include <process.h>
  7.  
  8.  
  9. #define BUFSIZE 512
  10. #define READ_BUFSIZE 5
  11.  
  12. HANDLE objects[1];
  13.  
  14. typedef struct
  15. {
  16.     OVERLAPPED ol;
  17.     HANDLE pipe;
  18.     HANDLE event_exit;
  19.  
  20.     /* in normal struct */
  21.     void *data;
  22.     int size;
  23.     unsigned int is_connected : 1;
  24.     unsigned int is_looping : 1;
  25. } Server;
  26.  
  27. #define LOCAL_APPEND_DATA(obj_, data_, size_) \
  28. do \
  29. { \
  30.     obj_->data = realloc(obj_->data, obj_->size + size_); \
  31.     if (obj_->data) \
  32.     { \
  33.         memcpy(obj_->data + obj_->size, data_, size_); \
  34.         obj_->data += size_; \
  35.     } \
  36. } while (0)
  37.  
  38.  
  39. void print_last_error(const char *fct)
  40. {
  41.     char *buf;
  42.     DWORD dw = GetLastError();
  43.  
  44.     FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  45.                   FORMAT_MESSAGE_FROM_SYSTEM |
  46.                   FORMAT_MESSAGE_IGNORE_INSERTS,
  47.                   NULL,
  48.                   dw,
  49.                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  50.                   (LPTSTR) &buf,
  51.                   0, NULL );
  52.  
  53.     fprintf(stderr, "%s failed with error %ld: %s\n", fct, dw, buf);
  54.     LocalFree(buf);
  55. }
  56.  
  57. void WINAPI
  58. IocpThreadProc(DWORD dwErrorCode,
  59.                DWORD dwNumberOfBytesTransfered,
  60.                LPOVERLAPPED lpOverlapped)
  61. {
  62.     char buf[READ_BUFSIZE];
  63.     Server *svr;
  64.     DWORD ret;
  65.     BOOL res;
  66.  
  67.     fprintf(stderr, " ** %ld, %ld\n", dwErrorCode, dwNumberOfBytesTransfered);
  68.  
  69.     svr = (Server *)lpOverlapped;
  70.  
  71.     /* check if client is connecting */
  72.  
  73.     if (!svr->is_connected)
  74.     {
  75.         res = ConnectNamedPipe(svr->pipe, &svr->ol);
  76.         /* in asynchronous mode, ConnectNamedPipe() always return FALSE */
  77.         if (res)
  78.         {
  79.             fprintf(stderr, "ConnectNamedPipe is failing (returning non 0 value)\n");
  80.         }
  81.         else
  82.         {
  83.             switch (GetLastError())
  84.             {
  85.                 /* client has connected between CreateNamedPipe() and ConnectNamedPipe ()*/
  86.                 case ERROR_PIPE_CONNECTED:
  87.                 {
  88.                     //fprintf(stderr, "client connected\n");
  89.                     svr->is_connected = 1;
  90.                     break;
  91.                 }
  92.                 /* connection with client is still pending */
  93.                 case ERROR_IO_PENDING:
  94.                 {
  95.                     fprintf(stderr, "connection pending\n");
  96.                     break;
  97.                 }
  98.                 case ERROR_NO_DATA:
  99.                 {
  100.                     fprintf(stderr, "client deconnected\n");
  101.                     break;
  102.                 }
  103.                 default:
  104.                 {
  105.                     fprintf(stderr, "ConnectNamedPipe is failing\n");
  106.                     break;
  107.                 }
  108.             }
  109.         }
  110.     }
  111.     //else
  112.     {
  113.         fprintf(stderr, "reading data\n");
  114.         ret = ReadFile(svr->pipe, buf, sizeof(buf), NULL, lpOverlapped);
  115.         if (!ret)
  116.         {
  117.             DWORD err = GetLastError();
  118.             if (err == ERROR_IO_PENDING)
  119.             {
  120.                 fprintf(stderr, "IO_PENDING\n");
  121.                 /* Let's wait for the event to be signaled  ?? */
  122.                 /* Call GetOverlappedResult ?? */
  123.             }
  124.             else if (ret == ERROR_BROKEN_PIPE)
  125.             {
  126.                 fprintf(stderr, "BROKEN_PIPE\n");
  127.                 SetEvent(svr->event_exit);
  128.             }
  129.             else
  130.             {
  131.                 print_last_error("unexpected error, ReadFile");
  132.                 SetEvent(svr->event_exit);
  133.             }
  134.         }
  135.         else
  136.         {
  137.             printf(" * ReadFile : %ld\n", dwNumberOfBytesTransfered);
  138.             LOCAL_APPEND_DATA(svr, buf, dwNumberOfBytesTransfered);
  139.             {
  140.                 char *msg=malloc(dwNumberOfBytesTransfered + 1);
  141.                 memcpy(msg, buf, dwNumberOfBytesTransfered);
  142.                 msg[dwNumberOfBytesTransfered] = 0;
  143.                 fprintf(stderr, "msg: %s\n", msg);
  144.             }
  145.         }
  146.     }
  147. }
  148.  
  149. Server *
  150. server_new(const char *name)
  151. {
  152.     char buf[256];
  153.     Server *svr;
  154.     HANDLE event;
  155.     BOOL res;
  156.  
  157.     if (!name)
  158.         return NULL;
  159.  
  160.     svr = (Server *)calloc(1,sizeof(Server));
  161.     if (!svr)
  162.         return NULL;
  163.  
  164.     snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", name);
  165.  
  166.     /*
  167.      * Asynchronuous I/O
  168.      * blocking mode
  169.      */
  170.     svr->pipe = CreateNamedPipe(buf,
  171.                                 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
  172.                                 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
  173.                                 PIPE_UNLIMITED_INSTANCES,
  174.                                 512, 512, 5000, NULL);
  175.     if (svr->pipe == INVALID_HANDLE_VALUE)
  176.     {
  177.         print_last_error("CreateNamedPipe");
  178.         goto free_svr;
  179.     }
  180.  
  181.     /*
  182.      * Manual reset
  183.      * Initial state : non signaled
  184.      */
  185.     event = CreateEvent(NULL, TRUE, FALSE, NULL);
  186.     if (!event)
  187.     {
  188.         print_last_error("CreateEvent");
  189.         goto close_pipe;
  190.     }
  191.  
  192.     memset(&svr->ol, 0, sizeof(svr->ol));
  193.     svr->ol.hEvent = event;
  194.  
  195.     res = ConnectNamedPipe(svr->pipe, &svr->ol);
  196.     /*
  197.      * in async mode, ConnectNamedPipe() should always return 0. If not, we exit
  198.      */
  199.     if (res)
  200.     {
  201.         print_last_error("ConnectNamedPipe");
  202.         goto close_event;
  203.     }
  204.     else
  205.     {
  206.         DWORD err = GetLastError();
  207.  
  208.         if (err == ERROR_PIPE_CONNECTED)
  209.         {
  210.             SetEvent(svr->ol.hEvent);
  211.             svr->is_connected = 1;
  212.             fprintf(stderr, "client connected\n");
  213.         }
  214.         else if (err != ERROR_IO_PENDING)
  215.         {
  216.             print_last_error("ConnectNamedPipe");
  217.             goto close_event;
  218.         }
  219.         else
  220.             fprintf(stderr, "connection pending...\n");
  221.         /* else, we have ERROR_IO_PENDING, so a connection link is pending */
  222.     }
  223.  
  224.     if (svr->is_connected)
  225.     {
  226.         char buf[READ_BUFSIZE];
  227.         BOOL ret;
  228.         ret = ReadFileEx(svr->pipe, buf, sizeof(buf), &svr->ol, IocpThreadProc);
  229.         if (!ret)
  230.         {
  231.             DWORD err = GetLastError();
  232.             if (err == ERROR_IO_PENDING)
  233.             {
  234.                 fprintf(stderr, "IO_PENDING\n");
  235.                 /* Let's wait for the event to be signaled  ?? */
  236.                 /* Call GetOverlappedResult ?? */
  237.             }
  238.             else if (ret == ERROR_BROKEN_PIPE)
  239.             {
  240.                 fprintf(stderr, "BROKEN_PIPE\n");
  241.                 SetEvent(svr->event_exit);
  242.             }
  243.             else
  244.             {
  245.                 print_last_error("ReadFile");
  246.                 //fprintf(stderr, "unexpected error\n");
  247.                 /* printf(" * unexpected error %ld\n", ret); */
  248.                 SetEvent(svr->event_exit);
  249.             }
  250.         }
  251.         else
  252.         {
  253.             printf(" * ReadFile 0\n");
  254.             /* LOCAL_APPEND_DATA(svr, buf, dwNumberOfBytesTransfered); */
  255.         }
  256.     }
  257.  
  258.     /*
  259.      * Manual reset
  260.      * Initial state : non signaled
  261.      */
  262.     svr->event_exit = CreateEvent(NULL, TRUE, FALSE, NULL);
  263.     if (!svr->event_exit)
  264.     {
  265.         print_last_error("CreateEvent (event exit)");
  266.         goto close_event;
  267.     }
  268.  
  269.     svr->is_looping = 1;
  270.  
  271.     objects[0] = svr->event_exit;
  272.  
  273.     BindIoCompletionCallback(svr->pipe, IocpThreadProc, 0);
  274.  
  275.     return svr;
  276.  
  277.   close_event:
  278.     CloseHandle(event);
  279.   close_pipe:
  280.     CloseHandle(svr->pipe);
  281.   free_svr:
  282.     free(svr);
  283.  
  284.     return NULL;
  285. }
  286.  
  287. void
  288. server_del(Server *svr)
  289. {
  290.     if (!svr)
  291.         return;
  292.  
  293.     CloseHandle(svr->event_exit);
  294.     if (!FlushFileBuffers(svr->pipe))
  295.     {
  296.         print_last_error("FlushFileBuffers");
  297.     }
  298.     if (!DisconnectNamedPipe(svr->pipe))
  299.     {
  300.         print_last_error("DisconnectNamedPipe");
  301.     }
  302.     CloseHandle(svr->ol.hEvent);
  303.     CloseHandle(svr->pipe);
  304.     free(svr);
  305. }
  306.  
  307. int main()
  308. {
  309.     Server *svr;
  310.     DWORD ret;
  311.  
  312.     svr = server_new("toto");
  313.     if (!svr)
  314.         return -1;
  315.  
  316.     printf("waiting for client...\n");
  317.  
  318.     while (svr->is_looping)
  319.     {
  320.         ret = WaitForSingleObject(objects[0], INFINITE);
  321.         if (ret == WAIT_FAILED)
  322.         {
  323.             print_last_error("WaitForMultipleObjects");
  324.             goto beach;
  325.         }
  326.         printf("WaitForSingleObject : %ld\n", ret);
  327.  
  328.         if (ret == WAIT_OBJECT_0)
  329.         {
  330.             ResetEvent(svr->ol.hEvent);
  331.             svr->is_looping = 0;
  332.         }
  333.     }
  334.  
  335.  beach:
  336.   server_del(svr);
  337.  
  338.   return 0;
  339. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement