Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* gcc -g -Wall -o server.exe server4.c */
- #include <stdio.h>
- #include <windows.h>
- #include <process.h>
- #define BUFSIZE 512
- HANDLE objects[3];
- typedef struct
- {
- HANDLE pipe;
- HANDLE event_exit;
- OVERLAPPED ol;
- OVERLAPPED ol_read;
- DWORD read_count;
- int exit_thread;
- /* in normal struct */
- void *data;
- int size;
- } Server;
- void print_last_error(const char *fct);
- static __stdcall unsigned int
- _read_data_cb(void *data)
- {
- #define READ_BUFSIZE 5
- char buf[READ_BUFSIZE];
- Server *svr;
- DWORD ret;
- DWORD nbr_bytes;
- BOOL res;
- svr = (Server *)data;
- while (!svr->exit_thread)
- {
- ret = ReadFile(svr->pipe, buf, sizeof(buf), &nbr_bytes, &svr->ol_read);
- if (!ret)
- {
- DWORD err = GetLastError();
- if (err == ERROR_IO_PENDING)
- {
- /* Let's wait for the event to be signaled ?? */
- /* Call GetOverlappedResult ?? */
- }
- else if (ret == ERROR_BROKEN_PIPE)
- {
- printf(" * broken pipe\n");
- SetEvent(svr->event_exit);
- }
- else
- {
- printf(" * unexpected error %ld\n", ret);
- SetEvent(svr->event_exit);
- }
- }
- else
- {
- printf(" * ReadFile : %ld\n", nbr_bytes);
- }
- }
- _endthreadex(0);
- return 0;
- }
- void print_last_error(const char *fct)
- {
- char *buf;
- DWORD dw = GetLastError();
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- dw,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &buf,
- 0, NULL );
- // Display the error message and exit the process
- printf("%s failed with error %ld: %s\n", fct, dw, buf);
- LocalFree(buf);
- }
- Server *
- server_new(const char *name)
- {
- char buf[256];
- Server *svr;
- HANDLE event;
- BOOL res;
- if (!name)
- return NULL;
- svr = (Server *)calloc(1,sizeof(Server));
- if (!svr)
- return NULL;
- snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", name);
- /*
- * Asynchronuous
- * block mode
- */
- svr->pipe = CreateNamedPipe(buf,
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
- PIPE_UNLIMITED_INSTANCES,
- 512, 512, 5000, NULL);
- if (!svr->pipe)
- {
- print_last_error("CreateNamedPipe");
- goto free_svr;
- }
- /*
- * Manual reset
- * Initial state : non signaled
- */
- event = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!event)
- {
- print_last_error("CreateEvent");
- goto close_pipe;
- }
- memset(&svr->ol, 0, sizeof(svr->ol));
- svr->ol.hEvent = event;
- res = ConnectNamedPipe(svr->pipe, &svr->ol);
- if (res)
- {
- print_last_error("ConnectNamedPipe");
- goto close_event;
- }
- else
- {
- DWORD err = GetLastError();
- if (err == ERROR_PIPE_CONNECTED)
- {
- SetEvent(svr->ol.hEvent);
- printf("client connected\n");
- }
- else if (err != ERROR_IO_PENDING)
- {
- print_last_error("ConnectNamedPipe");
- goto close_event;
- }
- /* else, we have ERROR_IO_PENDING, so a connection link is pending */
- }
- /*
- * Manual reset
- * Initial state : non signaled
- */
- svr->event_exit = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!svr->event_exit)
- {
- print_last_error("CreateEvent (event exit)");
- goto close_event;
- }
- /*
- * Manual reset
- * Initial state : non signaled
- */
- memset(&svr->ol_read, 0, sizeof(svr->ol_read));
- svr->ol_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!svr->ol_read.hEvent)
- {
- print_last_error("CreateEvent (event exit)");
- goto close_event_exit;
- }
- /* start reading the pipe */
- objects[0] = event;
- objects[1] = svr->event_exit;
- objects[2] = svr->ol_read.hEvent;
- return svr;
- close_event_exit:
- CloseHandle(svr->event_exit);
- close_event:
- CloseHandle(event);
- close_pipe:
- CloseHandle(svr->pipe);
- free_svr:
- free(svr);
- return NULL;
- }
- void
- server_del(Server *svr)
- {
- if (!svr)
- return;
- CloseHandle(svr->event_exit);
- if (!FlushFileBuffers(svr->pipe))
- {
- print_last_error("FlushFileBuffers");
- }
- if (!DisconnectNamedPipe(svr->pipe))
- {
- print_last_error("DisconnectNamedPipe");
- }
- CloseHandle(svr->ol.hEvent);
- CloseHandle(svr->pipe);
- free(svr);
- }
- int main()
- {
- Server *svr;
- DWORD ret;
- DWORD nbr_bytes;
- BOOL res;
- svr = server_new("toto");
- if (!svr)
- return -1;
- printf("waiting for client...\n");
- while (1)
- {
- ret = WaitForMultipleObjects(3, objects, FALSE, INFINITE);
- if (ret == WAIT_FAILED)
- {
- print_last_error("WaitForMultipleObjects");
- goto beach;
- }
- printf("WaitForMultipleObjects : %ld\n", ret);
- if (ret == WAIT_OBJECT_0)
- {
- ResetEvent(svr->ol.hEvent);
- res = GetOverlappedResult(svr->pipe, &svr->ol,
- &nbr_bytes, FALSE);
- if (!res)
- {
- print_last_error("GetOverlappedResult");
- if (!DisconnectNamedPipe(svr->pipe))
- {
- print_last_error("DisconnectNamedPipe");
- goto beach;
- }
- res = ConnectNamedPipe(svr->pipe, &svr->ol);
- if (res)
- {
- print_last_error("ConnectNamedPipe");
- goto beach;
- }
- else
- {
- DWORD err = GetLastError();
- if (err == ERROR_PIPE_CONNECTED)
- {
- SetEvent(svr->ol.hEvent);
- }
- else if (err != ERROR_IO_PENDING)
- {
- print_last_error("ConnectNamedPipe");
- goto beach;
- }
- /* else, we have ERROR_IO_PENDING, so a connection link is pending */
- }
- }
- else
- {
- printf("client connected (%d)\n", res);
- /* read pipe */
- _beginthreadex(NULL, 0, _read_data_cb, svr, 0, NULL);
- }
- }
- if (ret == (WAIT_OBJECT_0 + 1))
- {
- printf("client connection closed\n");
- svr->exit_thread = 1;
- goto beach;
- }
- if (ret == (WAIT_OBJECT_0 + 2))
- {
- ResetEvent(svr->ol_read.hEvent);
- /* res = GetOverlappedResult(svr->pipe, &svr->ol_read, */
- /* &nbr_bytes, TRUE); */
- /* if (res) printf(" nbr bytes : %ld\n", nbr_bytes); */
- /* else */
- /* print_last_error("GetOverlappedResult"); */
- }
- }
- beach:
- server_del(svr);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement