56 Chapter 2: Basic Sockets
■
on ErrorCode). If the timer expires, we increment the send attempt count (tries) and
start over. After the maximum number of tries, the while loop exits without receiv-
ing the datagram. If Receive() succeeds, we set the loop flag receivedResponse to
true, causing the loop to exit.
8. Print reception results: lines 58–63
If we received a datagram, receivedResponse is true, and we can print the datagram
data.
9. Close the socket: line 65
2.5.5 Socket Flags
The SocketFlags enumeration provides some additional ways to alter the default behav-
ior of individual Send()/SendTo() and Receive()/ReceiveFrom() calls. To use socket
flags the appropriate flag enumeration is simply passed as an argument to the send
or receive method. Although it is beyond the scope of this book to describe all the
socket flags available (see page 47 for a list), we present a simple code example here for
SocketFlags.Peek.
Peek allows you to view the contents of the next Receive()/ ReceiveFrom() without
actually dequeuing the results from the network-system buffer. What this means is that
you can create a copy of the contents of the next read, but the subsequent read will return
the same bytes again.
3
In theory this can be used to check the contents of the next read
and have the application make a decision on what to do based on that advance knowledge.
In practice, this is extremely inefficient (and, indeed, not always reliable [22]), and it is
almost always better to read the contents first and decide what to do with them afterwards.
However, we have included a code snippet here to illustrate the use of SocketFlags:
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
// Bind and/or Connect, create buffer
:
:
:
// Peek at the data without dequeuing it from the network buffer
int len = s.Receive(buf, 0, buf.Length, SocketFlags.Peek);
// This Receive will return (at least) the same data as the prior
// Receive, but this time it will be dequeued from the network buffer
len = s.Receive(buf, 0, buf.Length, SocketFlags.None);
3
In fact, if more bytes have been received over the network since the peek, the subsequent read might
return more data than the peek. The point is that unlike a nonpeek read, the bytes returned were not
removed from the buffer and are still available to be read again.