Sunday, April 20, 2008

What is peeking in TCP and why should it be avoided

Typical network receive operation via sockets looks like this:

socket.Receive(userBuffer, userBuffer.Length, SocketFlags.None);

In the above code received data is moved from Winsock internal buffers into the buffer specified by the user. Next time when socket.Receive is called another data chunk from TCP stream will be moved into the userBuffer.

On the other hand there is a receive method that is not moving data from system to user buffer but instead copies it. This process is called peeking.

Following code is peeking data from system buffer:
socket.Receive(userBuffer, userBuffer.Length, SocketFlags.Peek);

Every time Receive is called it copies the very same data from internal (system) buffer into user buffer.

One may ask why do wee need this peeking at all and why it is present in sockets API?

Peeking was introduced to preserve compatibility with Unix BSD sockets.
So, where one can use peeking? The answer is nowhere, do not use it at all when doing network I/O. Peeking is very inefficient and must be avoided.

1 comment:

  1. There is at least one rather cool usage of socket peeking, that I have seen.

    It was for a filtering process, that would allow multiple Apache web servers to coexist on the same system. The filter would peek at the incoming HTTP connection, without consuming the data. The purpose was to decide what Apache server should get it, and then hand the connection over to the Apache server, to fully read the data and handle the rest of the transaction.

    I don't want to spam your blog, but search for this: "msg_peek so_rcvlowat httpx".