I tried to use the HttpReceiveHttpRequest()
function with an LPOVERLAPPED
parameter as below:
//some predeclared parameter
LPOVERLAPPED myOverLapped;
myOverLapped->Internal = 0;
myOverLapped->InternalHigh = 0;
myOverLapped->DUMMYSTRUCTNAME.Offset = 0;
myOverLapped->DUMMYSTRUCTNAME.OffsetHigh = 0;
myOverLapped->Pointer = 0;
res = HttpReceiveHttpRequest(
RequestQueueHandle,
RequestId,
Flags,
RequestBuffer,
RequestBufferLength,
BytesReturned,
myOverLapped
);
if(ERROR_IO_PENDING == res)
while(!GetOverlappedResult(RequestQueueHandle,myOverLapped,RequestBufferLength,FALSE));
// other applications
However, I could hardly get a correct HTTP request from RequestBuffer
.
There must be something wrong, could you give me some help?
CodePudding user response:
Well, for one thing, the 3rd parameter of GetOverlappedResult()
expects a pointer to a DWORD
, but you are not giving it a pointer at all. You likely meant to pass it BytesReturned
instead of RequestBufferLength
.
more importantly, you are using an uninitialized OVERLAPPED*
pointer. You need to allocate an OVERLAPPED
instance for the pointer to point at, and don't free that OVERLAPPED
until the requested I/O operation is complete.
Try this:
LPOVERLAPPED myOverLapped = malloc(sizeof(OVERLAPPED));
memset(myOverLapped, 0, sizeof(OVERLAPPED));
myOverLapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
res = HttpReceiveHttpRequest(
RequestQueueHandle,
RequestId,
Flags,
RequestBuffer,
RequestBufferLength,
BytesReturned,
myOverLapped
);
if (ERROR_SUCCESS != res) {
if (ERROR_IO_PENDING != res) {
// error handling...
}
while (!GetOverlappedResult(RequestQueueHandle, myOverLapped, BytesReturned, FALSE)) {
if (ERROR_IO_INCOMPLETE != GetLastError()) {
// error handling...
}
// do something else in the meantime...
}
}
CloseHandle(myOverLapped->hEvent) ;
free(myOverLapped);
// use RequestBuffer up to BytesReturned as needed...
Alternatively, since you are waiting on the OVERLAPPED
in the same code that allocates it, you can just use a local variable instead of dynamic memory, eg:
OVERLAPPED myOverLapped;
memset(&myOverLapped, 0, sizeof(myOverLapped));
myOverLapped.hEvent = CreateEvent t(NULL, TRUE, FALSE, NULL);
res = HttpReceiveHttpRequest(
RequestQueueHandle,
RequestId,
Flags,
RequestBuffer,
RequestBufferLength,
BytesReturned,
&myOverLapped
);
if (ERROR_SUCCESS != res) {
if (ERROR_IO_PENDING != res) {
// error handling...
}
while (!GetOverlappedResult(RequestQueueHandle, &myOverLapped, BytesReturned, FALSE)) {
if (ERROR_IO_INCOMPLETE != GetLastError()) {
// error handling...
}
// do something else in the meantime...
}
}
CloseHandle(myOverLapped.hEvent);
// use RequestBuffer up to BytesReturned as needed...
Though, on the other hand, calling GetOverlappedResult()
to wait for a result the way you are doing negates the use of an OVERLAPPED
at all, so you may as well just get rid of it and use HttpReceiveHttpRequest()
synchronously instead:
res = HttpReceiveHttpRequest(
RequestQueueHandle,
RequestId,
Flags,
RequestBuffer,
RequestBufferLength,
BytesReturned,
NULL
);
if (ERROR_SUCCESS != res) {
// error handling...
}
// use RequestBuffer up to BytesReturned as needed...
CodePudding user response:
According to Synchronization and Overlapped Input and Output,
A thread can manage overlapped operations by either of two methods:
- Use the GetOverlappedResult or GetOverlappedResultEx function to wait for the overlapped operation to be completed. If GetOverlappedResultEx is used, the calling thread can specify a timeout for the overlapped operation or perform an alertable wait.
- Specify a handle to the OVERLAPPED structure's manual-reset event object in one of the wait functions and then, after the wait function returns, call GetOverlappedResult or GetOverlappedResultEx. The function returns the results of the completed overlapped operation, and for functions in which such information is appropriate, it reports the actual number of bytes that were transferred
And There is a Named Pipe Server Using Overlapped I/O sample in an asynchronous way.