/* gcc -g -Wall -o client.exe client2.c */
#include <stdio.h>
#include <string.h>
#include <windows.h>
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);
}
typedef struct
{
HANDLE pipe;
OVERLAPPED ol;
/* in normal struct */
void *data;
int size;
} Server;
Server *
server_new(const char *name)
{
char buf[256];
Server *svr;
if (!name)
return NULL;
printf("connecting to server...");
snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", name);
svr = (Server *)calloc(1, sizeof(Server));
if (!svr)
return NULL;
while (1)
{
svr->pipe = CreateFile(buf,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (svr->pipe != INVALID_HANDLE_VALUE)
break;
/* if pipe not busy, we exit */
if (GetLastError() != ERROR_PIPE_BUSY)
{
print_last_error("CreateFile");
goto free_svr;
}
/* pipe busy, so we wait for it */
if (!WaitNamedPipe(buf, NMPWAIT_WAIT_FOREVER))
{
print_last_error("WaitNamedPipe");
goto close_pipe;
}
}
printf(" done\n");
return svr;
close_pipe:
CloseHandle(svr->pipe);
free_svr:
free(svr);
printf(" failed\n");
return NULL;
}
void
server_del(Server *svr)
{
if (!svr)
return;
CloseHandle(svr->pipe);
free(svr);
}
void
server_data_send(Server *svr, const void *data, int size)
{
DWORD to_write;
DWORD written;
if (!svr || !data || (size <= 0))
return;
while (size > 0)
{
if (size <= 65535)
{
to_write = size;
size = 0;
}
else
{
to_write = 65535;
size -= 65535;
}
if (!WriteFile(svr->pipe, data, to_write, &written, NULL))
{
print_last_error("WriteFile");
break;
}
data += to_write;
/* should never happen */
if (written < to_write)
{
printf("WriteFile: insufficient buffer space\n");
}
}
}
void
server_data_get(Server *svr)
{
#define BUFSIZE 5
char buf[BUFSIZE];
void *data = NULL;
DWORD nbr_bytes_read;
int size = 0;
BOOL res;
if (!svr)
return;
do
{
res = ReadFile(svr->pipe, buf, sizeof(buf), &nbr_bytes_read, NULL);
if (!res)
{
if (GetLastError() == ERROR_MORE_DATA)
{
printf("more data\n");
continue;
}
else
{
print_last_error("ReadFile");
/* we keep current read data ? (i.e. no free(data) ? ) */
break;
}
}
if (res) printf("nbr : %ld\n", nbr_bytes_read);
if (res && (nbr_bytes_read > 0))
{
if (!data)
{
data = malloc(nbr_bytes_read);
if (!data)
break;
memcpy(data, buf, nbr_bytes_read);
size = nbr_bytes_read;
}
else
{
data = realloc(data, size + nbr_bytes_read);
if (!data)
{
size = 0;
break;
}
memcpy(data + size, buf, nbr_bytes_read);
size += nbr_bytes_read;
}
}
}
while (!res);
svr->data = data;
svr->size = size;
}
int main(void)
{
Server *svr;
svr = server_new("toto");
if (!svr)
return -1;
server_data_send(svr, "salut, c'est le client !", strlen("salut, c'est le client !"));
while (1)
{
server_data_get(svr);
if (svr->data)
{
char *buf;
buf = malloc(svr->size + 1);
memcpy(buf, svr->data, svr->size);
buf[svr->size] = '\0';
printf("client (%d) : %s\n", svr->size, buf);
free(svr->data);
svr->data = NULL;
Sleep(3000);
server_data_send(svr, "encore des donnees", strlen("encore des donnees"));
Sleep(2000);
break;
}
}
server_del(svr);
return 0;
}