Windows socket Extension function and socket Extension function

Source: Internet
Author: User

Windows socket Extension function and socket Extension function

1. AcceptEx ()

AcceptEx () is used to receive connections asynchronously and obtain the first piece of data sent by the client program.

 

[Cpp]View plaincopy
  1. BOOL AcceptEx (
  2. _ In _ SOCKET sListenSocket, // listen for SOCKET handle
  3. _ In _ SOCKET sAcceptSocket, // specify an unused SOCKET to receive new connections on this SOCKET
  4. _ In _ PVOID lpOutputBuffer, // specify a buffer to obtain the first data, local server address, and client address received on the new connection. This parameter must be specified
  5. _ In _ DWORD dwReceiveDataLength, // The data buffer size In lpOutputBuffer. This size does not include the local address of the server or the remote address of the client, 0 indicates that AcceptEx will establish a connection as soon as possible without waiting to receive any data.
  6. _ In _ DWORD dwLocalAddressLength, // The length reserved for the local address In the lpOutputBuffer buffer. It must be 16 longer than the maximum address length.
  7. _ In _ DWORD dwRemoteAddressLength, // The length reserved for the remote address In the lpOutputBuffer buffer. It must be 16 longer than the maximum address length.
  8. _ Out _ LPDWORD lpdwBytesReceived, // The length of the received data. This parameter is valid only when synchronization is complete. If the function returns ERROR_IO_PENDING and completes the operation later, the DWORD is meaningless. In this case, you must obtain the number of bytes read from the completion notification mechanism.
  9. _ In _ LPOVERLAPPED lpOverlapped // OVERLAPPED structure used to process the request. The value cannot be NULL.
  10. );


After AcceptEx () is successfully completed, three operations are performed: 1. A new connection is accepted; 2. Both the local address and remote address of the new connection are returned; 3. received the first piece of data from the remote host.

If no error occurs, the AcceptEx function is successfully completed and TRUE is returned.
If the function fails, AcceptEx returns FALSE. You can call the WSAGetLastError function to obtain the extended error information. If WSAGetLastError returns ERROR_IO_PENDING, this operation is successfully started and is still in progress.

If the data receiving buffer (dwReceiveDataLength is not 0) is provided, the overlapping operation of AcceptEx () delivery will not be completed until the connection is received and data is read. You can use the SO_CONNECT_TIME option of getsockopt to check whether a connection has been accepted. If it has been accepted, you can obtain how long the connection has been established (in seconds). If the socket is not connected, getsockopt returns 0 xFFFFFFFF. The application checks whether the overlap operation is complete and combines the SO_CONNECT_TIME option to determine whether the connection has been established for a period of time but has not received any data. We recommend that you close the connection to terminate the connection, so that AcceptEx () can complete the operation and return an error. For example:

int seconds;int bytes = sizeof(seconds);int iResult = 0;iResult = getsockopt(s, SOL_SOCKET, SO_CONNECT_TIME, (char *)&seconds, (PINT)&bytes);if (iResult != NO_ERROR) {    printf("getsockopt(SO_CONNECT_TIME) failed with error: %u\n", WSAGetLastError());}else {    if (seconds == 0xFFFFFFFF)        printf("Connection not established yet\n");    else        printf("Connection has been established %ld seconds\n", seconds);}

Compared with the accept function, the program uses AcceptEx to connect to a socket faster.

AcceptEx () is a Microsoft Extension function, which is from Mswsock. in the lib library, in order to be able to directly call it without link to Mswsock. lib Library (the program will be bound to the MicrosoftWinsock provider if you directly link to this library). You need to use WSAIoctl () to load AcceptEx () to the memory. WSAIoctl () is an extension of ioctlsocket (). It can use overlapping I/O. The input and output buffer ranges from 3rd to 6th parameters of the function, and AcceptEx () is passed here () function pointer. The details are as follows:

// Load extended function AcceptEx DWORD dwBytes; GUID GuidAcceptEx = signature; LPFN_ACCEPTEX Signature = NULL; int iResult = WSAIoctl (ListenSocket, signature, & GuidAcceptEx, sizeof (GuidAcceptEx), & signature, sizeof (lpfnAcceptEx), & dwBytes, NULL, NULL); if (iResult = SOCKET_ERROR) {printf ("WSAIoctl failed with error: % u \ n", WSAGetLastError ()); closesocket (ListenSocket); WSACleanup (); return 1 ;}...... // call AcceptExBOOL bRetVal = listen (ListenSocket, AcceptSocket, listen, outBufLen-(sizeof (sockaddr_in) + 16) * 2), sizeof (sockaddr_in) + 16, sizeof (LOGIN) + 16, & dwBytes, & olOverlap); if (bRetVal = FALSE) {printf (L "AcceptEx failed with error: % u \ n", WSAGetLastError ()); closesocket (AcceptSocket); closesocket (ListenSocket); WSACleanup (); return 1 ;}
 

2. GetAcceptExSockaddrs ()

GetAcceptExSockaddrs () is designed for AcceptEx (). It pastes the data obtained from AcceptEx () and transmits the local and remote addresses to the sockaddr structure.

Void GetAcceptExSockaddrs, // The size of the previous parameter, which should be consistent with the dwReceiveDataLength parameter of AcceptEx () _ In _ DWORD dwLocalAddressLength, // the size of the space reserved for the local address, which should be the same as that of AcceptEx () DwLocalAddressLength ParameterConsistent _ In _ DWORD dwRemoteAddressLength, // the size of the space reserved for the remote address, and DwRemoteAddressLengthConsistent parameter _ Out _ LPSOCKADDR * LocalSockaddr, // used to obtain the local connection address _ Out _ LPINT LocalSockaddrLength, // used to obtain the local connection address length _ Out _ LPSOCKADDR * RemoteSockaddr, // used to obtain the connection remote address _ Out _ LPINT RemoteSockaddrLength // used to obtain the connection remote address length); when using AcceptEx, the GetAcceptExSockaddrs function must be used to parse the content of the output buffer to three different buffers (data,
Local socket address, and remote socket address ). In windows XP and later versions, when the AcceptEx function is completed
When the SO_UPDATE_ACCEPT_CONTEXT option is set in the accepted socket, the local address (local
Address) can be obtained using the getsockname function. Similarly, the remote address related to the accepted socket can
To use the getpeername function. Use WSAIoctl () to load GetAcceptExSockaddrs ():
    DWORD dwBytes;    GUID GuidGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS;    LPFN_GETACCEPTEXSOCKADDRS lpfnGetAcceptExSockaddrs = NULL;    int Result = WSAIoctl(ListenSocket,        SIO_GET_EXTENSION_FUNCTION_POINTER,        &GuidGetAcceptExSockaddrs,        sizeof(GuidGetAcceptExSockaddrs),        &lpfnGetAcceptExSockaddrs,        sizeof(lpfnGetAcceptExSockaddrs),        &dwBytes,        NULL,        NULL);

3. TransmitFile

The TransmitFile () function uses the operating system's cache manager to send file data and provides high-performance file data transmission on the socket. the linux sendfile () and sendfile64 () functions are similar to the following:
Bool pascal TransmitFile (SOCKET hSocket, // connection SOCKET, cannot be SOCK_DGRAM or SOCK_RAM HANDLE hFile, // file HANDLE, in CreateFile () when opening a file, you can specify the FILE_FLAG_SEQUENTIAL_SCAN ID to improve the cache performance. DWORD nNumberOfBytesToWrite, // The bytes to be transferred. 0 indicates the size of the data block that is sent each time to transmit the entire file, 0 indicates the default size of LPOVERLAPPED lpOverlapped. // If the socket is created in an overlapped manner, specify this parameter to perform asynchronous I/O and specify the file offset, by default, the socket is created in the overlap mode? LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, // specifies the DWORD dwFlags of the data to be sent before and after the file data is sent. typedef void (* LPFN_TRANSMITFILE )();

If hFile is set to NULL, lpTransmitBuffers will be transmitted.
If lpOverlapped is NULL, the transfer starts from the current file pointer. Otherwise, the offset value in the OVERLAPPED structure specifies the file offset value.
TransmitFile () can only send 2 32 to the power minus 1 (about 2 GB) at a time. If this size is exceeded, set the nNumberOfBytesToWrite parameter to a non-0 value, call TransmitFile () multiple times.
DwFlags can be a combination of the following values:
We usually specify the first two flags at the same time. In this case, when the file or buffer data transmission operation is complete, the socket will be disconnected, and the socket passed to this function can be AcceptEx () or ctex () is used repeatedly, which can save the overhead of socket creation, because the overhead of socket creation is large.
If both hFile and lpTransmitBuffers are set to NULL (both the first two flags are specified), the function does not send any data, but sets the socket to allow reuse.
TransmitFile focuses on server applications. Therefore, its functions can be fully used only in the Windows Server version. For the Home edition or Professional Edition, there can be only two unfinished TransmitFile (or TransmitPackets) calls at any time. If this number is exceeded, the excess will be excluded, it is not processed until the invocation is completed.
SOCKET ConnectSocket = (SOCKET) lpParameter; HANDLE hFile = CreateFileA ("file. data ", GENERIC_READ, 0, NULL, OPEN_EXISTING, random, NULL); if (hFile = INVALID_HANDLE_VALUE) {int iErrno = WSAGetLastError (); printf (" createfile () error: % d \ n ", iErrno); return-1 ;} /*********************** a single call to TransmitFile () to send a file, synchronization Method **********************/BOOL bRet = FALSE; bRet = TransmitFile (C OnnectSocket, hFile, 0, 0, NULL/* & ov */, NULL, TF_USE_DEFAULT_WORKER); if (! BRet) {int iErrno = WSAGetLastError (); printf ("TransmitFile () failed: % d \ n", iErrno );} else {printf ("transfer end \ n ");} /*********************** call TransmitFile () multiple times to send a file, asynchronous mode **********************/OVERLAPPED ov; memset (& ov, 0, sizeof (ov); ov. hEvent = WSACreateEvent (); BOOL bRet = FALSE; int unsendDataSize = GetFileSize (hFile, NULL); int blockSize = 8192; if (blockSize> unsendDataSize) block Size = unsendDataSize; DWORD sendBytes, flags; while (1) {bRet = TransmitFile (ConnectSocket, hFile, blockSize, 0, & ov, NULL, TF_USE_DEFAULT_WORKER); if (! BRet) {int iErrno = WSAGetLastError (); if (iErrno = bytes | iErrno = ERROR_IO_PENDING) {bytes (ConnectSocket, & ov, & sendBytes, TRUE, & flags ); if (! Ov. internal) {unsendDataSize-= sendBytes; if (unsendDataSize = 0) {printf ("transfer end \ n"); break;} ov. offset + = sendBytes; if (blockSize> unsendDataSize) blockSize = unsendDataSize;} else {int iErrno = WSAGetLastError (); printf ("TransmitFile () failed: % d \ n ", iErrno); break ;}} else {printf ("TransmitFile () failed: % d \ n", iErrno); break ;}} else {if (! Ov. internal) {unsendDataSize-= sendBytes; if (unsendDataSize = 0) {printf ("transfer end \ n"); break;} ov. offset + = sendBytes; if (blockSize> unsendDataSize) blockSize = unsendDataSize;} else {int iErrno = WSAGetLastError (); printf ("TransmitFile () failed: % d \ n ", iErrno); break ;}}// close the connected socket closesocket (ConnectSocket); CloseHandle (hFile );
4、TransmitPackets()
TransmitPackets () is similar to TransmitFile (). The difference is that it can send data from multiple files or multiple memory buffers.

Bool pascal TransmitPackets (
SOCKET hSocket, // connection SOCKET, which can be SOCK_DGRAM
LPTRANSMIT_PACKETS_ELEMENT lpPacketArray, // array of encapsulation Elements
DWORD nElementCount, // Number of package elements in lpPacketArray
DWORD nSendSize, // the size of data sent each time
LPOVERLAPPED lpOverlapped, // same as TransmitFile ()

DWORD dwFlags // same as TransmitFile, but not starting with TF but starting with TP
);

Typedef void (* LPFN_TRANSMITPACKETS )();

The lpPacketArray package element array is an array of the LPTRANSMIT_PACKETS_ELEMENT structure type:

Typedef struct _ bytes {ULONG dwElFlags; // specify the buffer type contained in this element: file TP_ELEMENT_FILE or memory TP_ELEMENT_MEMORY or TP_ELEMENT_EOP ULONG cLength; // specify the number of bytes of the file to be transmitted, 0 indicates the union {struct {LARGE_INTEGER nFileOffset of the entire file; // the offset of the file.-1 indicates the HANDLE hFile is transferred from the current file pointer; // file HANDLE}; PVOID pBuffer; // data memory buffer};} TRANSMIT_PACKETS_ELEMENT;
The TP_ELEMENT_EOP flag of the dwElFlags member can be bitwise OR combined with the other two flags, indicating that the element should not be mixed with the following element during sending, this is used to precisely control the socket transmission for data packets or messages.
The use of TransmitFile () and TransmitPackets () not only improves the efficiency of File Sending, but also allows you to reuse the socket handle by specifying the TF_REUSE_SOCKET and TF_DISCONNECT flag. Every time the API completes data transmission, it will disconnect at the transport layer level, so that this socket can be re-provided to AcceptEx. Using this optimized programming method will reduce the pressure on the thread dedicated to the operation to create a socket.
5. ConnectEx ()

ConnectEx () is used for asynchronous connection calls. After a connection is established, data can also be sent. Because ConnectEx uses an asynchronous notification mechanism, if our client program requires multiple connections, you do not need to use one thread for each connection to manage the connection.
Bool pascal ConnectEx (_ In _ SOCKET s, // unconnected socket _ In _ const struct sockaddr * name, // remote address to be connected _ In _ int namelen, // remote address length _ In_opt _ PVOID lpSendBuffer, // The data to be sent after the connection is established. NULL indicates the length of data In _ DWORD dwSendDataLength, // lpSendBuffer
_ Out _ LPDWORD lpdwBytesSent, // the actual number of bytes sent
_ In _ LPOVERLAPPED lpOverlapped // overlapping structure, which must be specified );
The connection may not succeed immediately. In this case, ConnectEx () returns FALSE, and WSAGetLastError () is called to returnERROR_IO_PENDINGIndicates that the connection is in progress. If the error code is WSAECONNREFUSED, WSAENETUNREACH, or WSAETIMEDOUT, you can call ConnectEx again to connect.
When the connection succeeds or fails, the overlapping structure pointed to by lpOverlapped will be notified. You can use the event or the completion port as the notification mechanism.GetQueuedCompletionStatusOrGetOverlappedResultOrWSAGetOverlappedResultFunctionThe lpNumberOfBytesTransferred parameter can be used to obtain the number of bytes sent.
6. DisConnectEx ()
DisConnectEx () is used to close connections on the socket and allow reuse of the socket.
BOOL DisconnectEx (_ In _ SOCKET hSocket, // connection-oriented SOCKET _ In _ LPOVERLAPPED lpOverlapped, // If the SOCKET is created In an overlapping manner, specify this parameter to perform overlapping I/O operations _ In _ DWORD dwFlags, // TF_REUSE_SOCKET or 0, to disconnect only, TF_REUSE_SOCKET is reusable socket
_ In _ DWORD reserved // reserved );
If this function accepts an overlapping structure and there are still pending operations on the socket to be closed, it returns FALSE. The error code is WSA_IP_PENDING, once all pending operations on the socket are returned, the DisConnectEx () shipping operation will be completed.
If this function is called in blocking mode, it will be returned after all pending I/O is completed.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.