Miscellaneous API Functions

In this section, we'll cover a few Winsock API functions that you might find useful when you put together your own network applications.

getpeername

This function is used to obtain the peer's socket address information on a connected socket. The function is defined as

 int getpeername( SOCKET s, struct sockaddr FAR* name, int FAR* namelen ); 

The first parameter is the socket for the connection, while the last two parameters are a pointer to a SOCKADDR structure of the underlying protocol type and its length. For datagram sockets, this function returns the address passed to a connect call; however, it will not return the address passed to a sendto or WSASendTo call.

getsockname

This function is the opposite of getpeername. It returns the address information for the local interface of a given socket. The function is defined as follows:

 int getsockname( SOCKET s, struct sockaddr FAR* name, int FAR* namelen ); 

The parameters are the same as the getpeername parameters except that the address information returned for socket s is the local address information. In the case of TCP, the address is the same as the server socket listening on a specific port and IP interface.

WSADuplicateSocket

The WSADuplicateSocket function is used to create a WSAPROTOCOL_INFO structure that can be passed to another process, thus enabling the other process to open a handle to the same underlying socket so that it too can perform operations on that resource. Note that this is only necessary between processes; threads in the same process can freely pass the socket descriptors. This function is defined as

 int WSADuplicateSocket( SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFO lpProtocolInfo ); 

The first parameter is the socket handle to duplicate. The second parameter, dwProcessId, is the process ID of the process that intends to use the duplicated socket. Third, the lpProtocolInfo parameter is a pointer to a WSAPROTOCOL_INFO structure that will contain the necessary information for the target process to open a duplicate handle. Some form of interprocess communication must occur so that the current process can pass the WSAPROTOCOL_INFO structure to the target process, which then uses this structure to create a handle to the socket (using the WSASocket function).

The descriptors in both sockets can be used independently for I/O; however, Winsock provides no access control, so it is up to the programmer to enforce some kind of synchronization. All of the state information associated with a socket is held in common across all the descriptors because the socket descriptors are duplicated, not the actual socket. For example, any socket option set by the setsockopt function on one of the descriptors is subsequently visible using the getsockopt function from any or all descriptors. If a process calls closesocket on a duplicated socket, it causes the descriptor in that process to become deallocated; however, the underlying socket will remain open until closesocket is called on the last remaining descriptor.

Additionally, be aware of some issues with notification on shared sockets when using WSAAsyncSelect and WSAEventSelect. These two functions are used in asynchronous I/O (discussed in Chapter 8). Issuing either of these calls using any of the shared descriptors cancels any previous event registration for the socket, regardless of which descriptor was used to make that registration. Thus, for example, a shared socket cannot deliver FD_READ events to process A and FD_WRITE events to process B. If you require event notifications on both descriptors, you should rethink the design of your application to use threads as opposed to processes.

TransmitFile

TransmitFile is a Microsoft-specific Winsock extension that allows for high-performance data transfers from a file. This is efficient is because the entire data transfer can occur in kernel mode. That is, if your application reads a chunk of data from the file and then uses send or WSASend, there are multiple send calls that involve user-mode-to-kernel-mode transitions. With TransmitFile, the entire read and send process is performed in kernel mode. The function is defined as

 BOOL TransmitFile( SOCKET hSocket, HANDLE hFile, DWORD nNumberOfBytesToWrite, DWORD nNumberOfBytesPerSend, LPOVERLAPPED lpOverlapped, LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, DWORD dwFlags ); 

The hSocket parameter identifies the connected socket on which to transfer the file. The hFile parameter is a handle to an opened file. (This is the file that will be sent.) The nNumberOfBytesToWrite indicates how many bytes to write from the file. Passing 0 indicates the entire file should be sent. The nNumberOfBytesPerSend parameter indicates the send size to use for write operations. For example, specifying 2048 causes TransmitFile to send the given file on the socket in 2-KB chunks. Passing 0 indicates using the default send size. The lpOverlapped parameter specifies an OVERLAPPED structure that is used in overlapped I/O. (See Chapter 8 for information on overlapped I/O.)

The next parameter, lpTransmitBuffers, is a TRANSMIT_FILE_BUFFERS structure that contains data to be sent before and after the file transfer. The structure is defined as

 typedef struct _TRANSMIT_FILE_BUFFERS { PVOID Head; DWORD HeadLength; PVOID Tail; DWORD TailLength; } TRANSMIT_FILE_BUFFERS; 

The Head field is a pointer to the data to send before transmitting the file. HeadLength indicates the amount of data to send beforehand. The Tail field points to the data to send after the file is transmitted. TailLength is the number of bytes to send afterward.

The last parameter of TransmitFile, dwFlags, is used to specify flags to affect the behavior of TransmitFile. Table 7-2 contains the flags and their explanations.

Table 7-2. TransmitFile flags

Flag Description
TF_DISCONNECT Initiates socket closure after data has been sent.
TF_REUSE_SOCKET Allows the socket handle to be reused in AcceptEx as a client socket.
TF_USE_DEFAULT_WORKER Indicates that the transfer should take place in the context of the system's default thread. This is useful for long file transfers.
TF_USE_SYSTEM_THREAD Indicates that the transfer should take place in the context of the system thread. This is also useful for long file transfers.
TF_USE_KERNEL_APC Indicates that kernel Asynchronous Procedure Calls (APC) should process the file transfer. This can offer a significant performance increase if reading the file into the cache requires only one read.
TF_WRITE_BEHIND Indicates that TransmitFile should complete without having all the data acknowledged by the remote system.



Network Programming for Microsoft Windows
Linux Server Hacks, Volume Two: Tips & Tools for Connecting, Monitoring, and Troubleshooting
ISBN: 735615799
EAN: 2147483647
Year: 1998
Pages: 159

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net