Sign in to follow this  

some IOCP questions

This topic is 3573 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

You will know that the client has sent data that you have received when your IOCP thread receives a completion event for the queued read request.

You can send a structure just like any other data; pass a pointer to it and a size to the overlapped write request.

Share this post


Link to post
Share on other sites
I believe the hEvent is not used with IO Completion Ports.

MSDN says it is used to signal when the operation has completed. Since you are using IOCP, you have a different mechanism for that signal.

A trick to help you is to create your own structure or class that holds an OVERLAPPED structure as it's first member. This allows you to figure out what IO has completed.


typedef struct tagIONotifyData
{
OVERLAPPED structOverlapped;
LPVOID pUserData;
} IO_NOTIFY_DATA, *PIO_NOTIFY_DATA;




Happy coding.

Share this post


Link to post
Share on other sites
Am i stupid or what i can understand everything else except the thing how they switch cases with operation type. I cant understand where they get operation type from socket.

BOOL bIORet = GetQueuedCompletionStatus(
hCompletionPort,
&dwIoSize,
(LPDWORD) &lpClientContext,
&lpOverlapped, INFINITE);

switch(smth->op_code){

case RECV:

case SEND:

}

Share this post


Link to post
Share on other sites
Like LordShade said:


struct Something {
OVERLAPPED overlapped;
int op_code;
HFILE socket;
void *buffer;
size_t size;
... whatever else ...
};


Something *foo = new Something;
memset(foo, 0, sizeof(foo));
foo->overlapped = ...;
foo->op_code = WRITE;
foo->socket = mySocket; // must have been opened with OVERLAPPED status
foo->buffer = myBuffer;
foo->size = mySize;
WriteFile(foo->socket, foo->buffer, foo->size, 0, &foo->overlapped);

DWORD clientContext;
Something *something;
GetQueuedCompletionStatus(hPort, &dwIoSize, &clientContext, (OVERLAPPED *)&something, INFINITE);

switch (something->op_code) {
}

Share this post


Link to post
Share on other sites
Pumped into another question. When sending messages with WSASend(), do i have to post data into IOCP first and then use WSASend. Or i can just use WSASend. Then that leaves for IOCP thread only read operation.

Share this post


Link to post
Share on other sites
You just use WSASend(). It posts the overlapped IO request into a queue which is serviced by your thread.
And you'll know that it's a write rather than a read because you'll set the operation type to write in your derived OVERLAPPED struct if you need to.

Share this post


Link to post
Share on other sites
Quote:
Original post by TiitHns
But how to take care of that partial packet what has been sent extra. This happens if 2 packets exceed maximum size.
There aren't any packets - it's TCP. TCP doesn't have a concept of packets.

If you need support for packets, either use UDP, or build support on top of TCP by doing something like prefixing each "packet" with it's length in bytes. Then when you read it out, you can only read out full packets.

Share this post


Link to post
Share on other sites
Here the problem wht happens with buffer size;

i send data from client (Header{ ID } + Contentcs { DATA })
If there is buffer limit. It sometimes merges some other header to without data and i get it with second WSARecv order. But then the header is missing and i have unknown data.

Share this post


Link to post
Share on other sites
Quote:
Original post by TiitHns
Here the problem wht happens with buffer size;

i send data from client (Header{ ID } + Contentcs { DATA })
If there is buffer limit. It sometimes merges some other header to without data and i get it with second WSARecv order. But then the header is missing and i have unknown data.
But you know the size of the data the header is merged to, because there's a header on that data. So you know the offset of the next header.

Your recv code will looks like (semi-psuedocode):

std::vector<unsigned char> buffer;

while(true)
{
// Read in as much data as possible
read_from_socket(buffer);

// Do we have a packet length?
if(buffer.size() < 2)
break;
unsigned short packet_len = *(unsigned short*)&buffer[0];

// Do we have the whole packet in the buffer?
if(buffer.size() < packet_len + 2)
break;

// Extract packet
process_packet(&buffer[2], packet_len);
buffer.erase(buffer.begin(), buffer.begin() + packet_len + 2);
}


In that code, you buffer data until you get a full packet, and then you process that packet and trim it out of the buffer.

Share this post


Link to post
Share on other sites

This topic is 3573 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this