Transmitfile and TransmitPackets
Winsock provides two functions that have been optimized for file and memory data transfer. Where TransmitFile () This API function can be used on Windows NT 4.0 and Windows 2000, while transmitpackets () will be implemented in future versions of Windows.
TransmitFile () is used to transfer the file content through Winsock. Usually send files, first modify CREATEFILE () to open a file, and then call ReadFile () and wsasend () until the data is sent. But this method is very efficient because each call readFile () and wsasend () will involve the conversion from user mode to kernel mode. If you replace it with transmitfile (), then only need to give it a handle of the file and the number of bytes to be sent, and the mode conversion operation involved will only occur once when CreateFile () is invoked, then transmitfile () A occurs again. This efficiency is much higher.
TRANSMITPACKETS () is further further, which allows users to send only multiple files and memory buffers that can be sent only once. The following function prototype: BOOL TransmitPackets (SOCKET hSocket, LPTRANSMIT_PACKET_ELEMENT lpPacketArray, DWORD nElementCount, DWORD nSendSize, LPOVERLAPPED lpOverlapped, DWORD dwFlags); wherein, lpPacketArray structure is an array, where each element can be either a memory buffer or a file handle the structure is defined as follows: typedef struct _TRANSMIT_PACKETS_ELEMENT {DWORD dwElFlags; DWORD cLength; union {struct {LARGE_INTEGER nFileOffset; HANDLE hFile;}; PVOID pBuffer;};} TRANSMIT_FILE_BUFFERS; wherein each field is self-describing type (self explanatory). DWELFLAGS field: Specify whether the current element is a file handle or a memory buffer (specified by constant TF_ELEMENT_FILE and TF_ELEMENT_MEMORY); CLENGTH field: Specifies the number of bytes that will be sent from the data source (if it is a file, this field value is 0 means sending the entire File); Unnamed Uniforms in the structure: Contains the memory buffer (and possible offset) of the file handle.
Another benefit of using these two APIs is that you can reuse the socket by specifying the TF_REUSE_SOCKET and TF_DISCONNECT flags. Whenever the API completes the data transfer operation, it will be disconnected at the transfer layer level, so that this socket can be re-supplied to AccePtex (). This optimized method programming will alleviate the pressure of the thread that is specially accepted (pre-explanation and).
These two APIs also have a common weaknesses: Windows NT Workstation or Windows 2000 Professional, the function can only handle two call requests each time, only in Windows NT, Windows 2000 Server Edition, Windows 2000 Advanced Server or Windows Full support is obtained in 2000 Data Center. Look down together
In the above sections, we discussed the development of functions, methods, and resources that may be encountered by developing high-performance, large responding applications. What does these mean you? In fact, this depends on how you construct your server and client. When you can better control on the server and client design, then you can avoid bottleneck problems.
Look at a demonstration environment. We want to design a server to respond to the client's connection, send request, receive data, and disconnect. Then, the server will need to create a listener sleeve and associate it with a completion port and create a work thread for each CPU. Create a thread to specifically use AcceptEx (). We know that the client will send data immediately after issuing a connection request, so if we are ready to receive buffers, it makes it easier. Of course, don't forget to poll the sockets used from timeproof () to ensure that there is no malicious timeout connection from time to time (using the SO_CONNECT_TIME Option parameters).
There is an important issue in this design to consider, we should allow how many acceptex () will wait. This is because we need to provide an Acceptex () we need to provide a receive buffer for it, then there will be many locked pages in memory (previously said, each overlap can consume a small part Paging memory pools while also locking all buffers involved). This problem is difficult to answer, there is no exact answer. The best way is to make this value can be adjusted. By repeated performance test, you can get the best value in a typical application environment.
Ok, when you measure clearly, the following is the problem of sending data. Consideration is the focus of you want the server to handle how many concurrent connections. Typically, the server should limit the number of concurrent connections and the transmission call waiting for processing. Because the number of concurrent connections, the more memory pools consumed; the more transmission calls that are waiting, the more memory pages are locked (balanced, don't exceed the limit). This also requires repeated test to know the answer.
For the above environment, there is usually no need to turn off a single socket buffer because it is not too difficult to provide a buffer that receives data only in AcceptEx (). However, if the client interacts with the server changes, the client needs to send more data after sending the data, and it is not very wonderful in this case, unless you want to guarantee Overlapping reception calls are issued on each connection to receive more data.
in conclusion
The Winsock server that develops a big response scale is not very terrible, in fact, it is to set a listener sleeve, accept the connection request and overlap transmission and reception call. By setting a reasonable amount of overlapping calls, preventing the memory pool from being exhausted, this is the most important challenge. According to some of the principles we have previously discussed, you can develop a larger responsible server application.
(Translator) Liu Xi SICKID10001@21cn.com