Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* gcc -g -Wall -o server.exe server3.c */
- #include <stdio.h>
- #include <windows.h>
- #include <process.h>
- #define BUFSIZE 512
- #define READ_BUFSIZE 5
- HANDLE objects[1];
- typedef struct
- {
- OVERLAPPED ol;
- HANDLE pipe;
- HANDLE event_exit;
- /* in normal struct */
- void *data;
- int size;
- unsigned int is_connected : 1;
- unsigned int is_looping : 1;
- } Server;
- #define LOCAL_APPEND_DATA(obj_, data_, size_) \
- do \
- { \
- obj_->data = realloc(obj_->data, obj_->size + size_); \
- if (obj_->data) \
- { \
- memcpy(obj_->data + obj_->size, data_, size_); \
- obj_->data += size_; \
- } \
- } while (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 );
- fprintf(stderr, "%s failed with error %ld: %s\n", fct, dw, buf);
- LocalFree(buf);
- }
- void WINAPI
- IocpThreadProc(DWORD dwErrorCode,
- DWORD dwNumberOfBytesTransfered,
- LPOVERLAPPED lpOverlapped)
- {
- char buf[READ_BUFSIZE];
- Server *svr;
- DWORD ret;
- BOOL res;
- fprintf(stderr, " ** %ld, %ld\n", dwErrorCode, dwNumberOfBytesTransfered);
- svr = (Server *)lpOverlapped;
- /* check if client is connecting */
- if (!svr->is_connected)
- {
- res = ConnectNamedPipe(svr->pipe, &svr->ol);
- /* in asynchronous mode, ConnectNamedPipe() always return FALSE */
- if (res)
- {
- fprintf(stderr, "ConnectNamedPipe is failing (returning non 0 value)\n");
- }
- else
- {
- switch (GetLastError())
- {
- /* client has connected between CreateNamedPipe() and ConnectNamedPipe ()*/
- case ERROR_PIPE_CONNECTED:
- {
- //fprintf(stderr, "client connected\n");
- svr->is_connected = 1;
- break;
- }
- /* connection with client is still pending */
- case ERROR_IO_PENDING:
- {
- fprintf(stderr, "connection pending\n");
- break;
- }
- case ERROR_NO_DATA:
- {
- fprintf(stderr, "client deconnected\n");
- break;
- }
- default:
- {
- fprintf(stderr, "ConnectNamedPipe is failing\n");
- break;
- }
- }
- }
- }
- //else
- {
- fprintf(stderr, "reading data\n");
- ret = ReadFile(svr->pipe, buf, sizeof(buf), NULL, lpOverlapped);
- if (!ret)
- {
- DWORD err = GetLastError();
- if (err == ERROR_IO_PENDING)
- {
- fprintf(stderr, "IO_PENDING\n");
- /* Let's wait for the event to be signaled ?? */
- /* Call GetOverlappedResult ?? */
- }
- else if (ret == ERROR_BROKEN_PIPE)
- {
- fprintf(stderr, "BROKEN_PIPE\n");
- SetEvent(svr->event_exit);
- }
- else
- {
- print_last_error("unexpected error, ReadFile");
- SetEvent(svr->event_exit);
- }
- }
- else
- {
- printf(" * ReadFile : %ld\n", dwNumberOfBytesTransfered);
- LOCAL_APPEND_DATA(svr, buf, dwNumberOfBytesTransfered);
- {
- char *msg=malloc(dwNumberOfBytesTransfered + 1);
- memcpy(msg, buf, dwNumberOfBytesTransfered);
- msg[dwNumberOfBytesTransfered] = 0;
- fprintf(stderr, "msg: %s\n", msg);
- }
- }
- }
- }
- 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 I/O
- * blocking mode
- */
- svr->pipe = CreateNamedPipe(buf,
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
- PIPE_UNLIMITED_INSTANCES,
- 512, 512, 5000, NULL);
- if (svr->pipe == INVALID_HANDLE_VALUE)
- {
- 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);
- /*
- * in async mode, ConnectNamedPipe() should always return 0. If not, we exit
- */
- if (res)
- {
- print_last_error("ConnectNamedPipe");
- goto close_event;
- }
- else
- {
- DWORD err = GetLastError();
- if (err == ERROR_PIPE_CONNECTED)
- {
- SetEvent(svr->ol.hEvent);
- svr->is_connected = 1;
- fprintf(stderr, "client connected\n");
- }
- else if (err != ERROR_IO_PENDING)
- {
- print_last_error("ConnectNamedPipe");
- goto close_event;
- }
- else
- fprintf(stderr, "connection pending...\n");
- /* else, we have ERROR_IO_PENDING, so a connection link is pending */
- }
- if (svr->is_connected)
- {
- char buf[READ_BUFSIZE];
- BOOL ret;
- ret = ReadFileEx(svr->pipe, buf, sizeof(buf), &svr->ol, IocpThreadProc);
- if (!ret)
- {
- DWORD err = GetLastError();
- if (err == ERROR_IO_PENDING)
- {
- fprintf(stderr, "IO_PENDING\n");
- /* Let's wait for the event to be signaled ?? */
- /* Call GetOverlappedResult ?? */
- }
- else if (ret == ERROR_BROKEN_PIPE)
- {
- fprintf(stderr, "BROKEN_PIPE\n");
- SetEvent(svr->event_exit);
- }
- else
- {
- print_last_error("ReadFile");
- //fprintf(stderr, "unexpected error\n");
- /* printf(" * unexpected error %ld\n", ret); */
- SetEvent(svr->event_exit);
- }
- }
- else
- {
- printf(" * ReadFile 0\n");
- /* LOCAL_APPEND_DATA(svr, buf, dwNumberOfBytesTransfered); */
- }
- }
- /*
- * 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;
- }
- svr->is_looping = 1;
- objects[0] = svr->event_exit;
- BindIoCompletionCallback(svr->pipe, IocpThreadProc, 0);
- return svr;
- 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;
- svr = server_new("toto");
- if (!svr)
- return -1;
- printf("waiting for client...\n");
- while (svr->is_looping)
- {
- ret = WaitForSingleObject(objects[0], INFINITE);
- if (ret == WAIT_FAILED)
- {
- print_last_error("WaitForMultipleObjects");
- goto beach;
- }
- printf("WaitForSingleObject : %ld\n", ret);
- if (ret == WAIT_OBJECT_0)
- {
- ResetEvent(svr->ol.hEvent);
- svr->is_looping = 0;
- }
- }
- beach:
- server_del(svr);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement