• Advertisement
Sign in to follow this  

some IOCP questions

This topic is 3646 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

Q1. How to determine if client is sending data or not? Can i use there FD_READ? by creating Event? Q2. How to send structure packet with IOCP? [Edited by - TiitHns on February 9, 2008 3:16:59 PM]

Share this post


Link to post
Share on other sites
Advertisement
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
Yes that i understand but i dont get how it goes to READ case, there op_code should be set automatically.

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
What causes such Thing. I send with client 10 packets in row with message "Hello", when server recv-s them it shows 1. HelloHelloHello 2. HelloHello. Basicly it glues them togheter.

Share this post


Link to post
Share on other sites
But how to take care of that partial packet what has been sent extra. This happens if 2 packets exceed maximum size.

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
Sign in to follow this  

  • Advertisement