The code is rather large. Dont say i didnt warn you.
This is the Struct I am sending through. DATASIZE = 1024.
Code:
struct Instruction
{
int StructID;
int Size;
char Data[DATASIZE]; // User defined Data (ie. Custom structs etc.)
};
My pipe structure, contains all the necessary things for getting a pipe started.
Code:
typedef struct
{
OVERLAPPED Overlap;
HANDLE PipeInst;
DWORD Read;
DWORD ToWrite;
DWORD State;
BOOL PendingIO;
DWORD Id;
} PIPEINST;
This code creates a pipe on the CLIENT side.
Code:
bool Pipe::Create()
{
char PipeName[35];
PipeInst.Id = (DWORD) App;
memset(PipeName, 0, 35);
sprintf(PipeName, "\\\\.\\pipe\\%X", PipeInst.Id);
// Create an event to use with overlapping
Events = CreateEvent(
NULL, // default security attribute
TRUE, // manual-reset event
TRUE, // initial state = signaled
NULL); // unnamed event object
if (Events)
{
// Set the new overlap event
PipeInst.Overlap.hEvent = Events;
PipeInst.PipeInst = CreateNamedPipe(
PipeName, // pipe name
PIPE_ACCESS_DUPLEX | // read/write access
FILE_FLAG_OVERLAPPED, // overlapped mode (asych mode)
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT, // blocking mode
1, // number of instances
BUFSIZE, // output buffer size
BUFSIZE, // input buffer size
PIPE_TIMEOUT, // client time-out
NULL); // default security attributes
// Attempt to connect to the newly created pipe
PipeInst.PendingIO = ConnectToNewClient(
PipeInst.PipeInst,
&PipeInst.Overlap);
if (PipeInst.PendingIO)
{
SendMessage(Service, STRIKE_REGISTER_APPLICATION, (WPARAM) PipeInst.Id, NULL);
}
}
return PipeInst.PendingIO ? true : false;
}
This code Connects to the pipe from the SERVER side:
Code:
bool Pipe::Connect(char *PipeName)
{
bool Rtrn = false;
if (PipeName)
{
// Attempt to connect to a pipe
PipeInst.PipeInst = CreateFile(
PipeName, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
// If we have a good handle then exit correctly
if (PipeInst.PipeInst != INVALID_HANDLE_VALUE)
{
Rtrn = true;
}
}
return Rtrn && PipeInst.PipeInst ? true : false;
}
Here the CLIENT reads from the pipe whenever there is a new piece of data available (i do this by notifying the client by using SendMessage() with a custom windows message).
Code:
void *Pipe::GetData(int *StructID)
{
void *Rtrn = NULL;
Instruction RecieveData;
unsigned int Written = 0;
if (PipeInst.PipeInst)
{
memset(&RecieveData, 0, sizeof(Instruction));
// Get the size of the Buffer
ReadFile(
PipeInst.PipeInst, // pipe handle
&RecieveData, // buffer to receive reply
sizeof(Instruction),// size of buffer
(LPDWORD) &Written, // number of bytes read
NULL); // not overlapped
Rtrn = (void *) new unsigned char[RecieveData.Size];
if (Rtrn)
{
memcpy(Rtrn, &RecieveData.Data, (size_t) RecieveData.Size);
*StructID = RecieveData.StructID;
}
}
return Rtrn;
}
This is on the server side, where the server send data down the pipe and then sends a message to the client saying there is date to be read.
Code:
bool Pipe::WriteData(void *Data, int Size, int StructID)
{
bool Rtrn = false;
unsigned int Written = 0;
Instruction DataSend;
if (PipeInst.PipeInst && Data && Size)
{
memset(&DataSend, 0, sizeof(Instruction));
DataSend.Size = Size;
DataSend.StructID = StructID;
memcpy(&DataSend.Data, Data, Size);
WriteFile(
PipeInst.PipeInst, // pipe handle
&DataSend, // message
sizeof(Instruction), // message length
(LPDWORD) &Written, // bytes written
NULL); // not overlapped
if (Written == sizeof(Instruction))
{
SendMessage(App, STRIKE_RECIEVED_INSTRUCTION, NULL, NULL);
Rtrn = true;
}
}
return Rtrn;
}
OK that was long. Basically it works this way. The CLIENT creates a pipe, then sends a message to the SERVER saying "hey, theres a pipe created, talk to me". The server connects to the pipe and starts writing data. When data is written, it sends a message to the CLIENT saying "hey, thers data to be read". The client then reads the data.
I believe that the problem might be that the pipe gets two structs sent down the pipe before the client is able to pick it up. the client app is firefox, so therefore it may not have the time to read form the message pump as frequently.
Thats my interpretation of this. Am i right or can someone offer some other solution?