Sending and receiving PGM data is similar to sending or receiving data on any socket. There are considerations specific to PGM, outlined in the following paragraphs.
Sending PGM DataOnce a PGM sender session is created, data is sent using the various Windows Sockets send functions: send, sendto, WSASend, and WSASendTo. Since Windows Sockets handles are file system handles, other functions such as WriteFile and CRT functions can also transmit data. The following code snippet illustrates a PGM sender operation:
LONG error;
//:
error = send (s, pSendBuffer, SendLength, 0);
if (error == SOCKET_ERROR)
{
fprintf (stderr, "send() failed: Error = %d\n",
WSAGetLastError());
}
When using message mode (SOCK_RDM), each call to a send function results in a discrete message, which sometimes isn't desirable; an application may want to send a 2 megabyte message with multiple calls to send. In such circumstances, the sender can set the RM_SET_MESSAGE_BOUNDARY socket option to indicate the size of the message that followings.
If the send window is full, a new send from the application is not accepted until window has been advanced. Attempting to send on a non-blocking socket fails with WSAEWOULDBLOCK; a blocking socket simply blocks until the window advances to the point where the requested data can be buffered and sent. In overlapped I/O, the operation does not complete until the window advances enough to accommodate the new data.
Receiving PGM DataOnce a PGM receiver session is created, data is received using the various Windows Sockets receive functions: recv, recvfrom, WSARecv, and WSARecvFrom. Since Windows Sockets handles are also file handles, the ReadFile and CRT functions can also be used to receive PGM session data. The transport forwards data up to the receiver as it arrives as long as the data is in sequence. The transport guarantees that the data returned is contiguous and free of duplicates. The following code snippet illustrates a PGM receive operation:
LONG BytesRead;
//:
BytesRead = recv (sockR, pTestBuffer, MaxBufferSize, 0);
if (BytesRead == 0)
{
fprintf(stdout, "Session was terminated\n");
}
else if (BytesRead == SOCKET_ERROR)
{
fprintf(stderr, "recv() failed: Error = %d\n",
WSAGetLastError());
}
When using message mode (SOCK_RDM), the transport indicates when a partial message is received, either with the WSAEMSGSIZE error, or by setting the MSG_PARTIAL flag upon return from the WSARecv and WSARecvFrom functions. When the last fragment of the full message is returned to the client, the error or flag is not indicated.
When the session is terminated gracefully, the receive operation fails with WSAEDISCON. When data loss occurs in the transport, PGM temporarily buffers the out-of-sequence packets and attempts to recover the lost data. If the data-loss is unrecoverable, the receive operation fail with WSAECONNRESET, and the session is terminated. The session can be reset due to a variety of conditions, including the following:
Both the first and second items in the above list could result in the receiver performing excessive buffering before running out of resources, or before ultimately moving beyond the sender's window.
Terminating A PGM SessionThe PGM sender or receiver can stop sending or receiving data by calling closesocket. The receiver must call closesocket on both the listening and receiving sockets to prevent handle leaks. Calling shutdown on the sender before calling closesocket ensures all data gets sent, and ensures repair data is maintained until the send window advances past the last data sequence, even if the application itself terminates.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4