Iocp to SOCKET Communications (reprint)
Since the choice hxzb7215191 Blog
Of course the model is also available in TCP mode incident choice model.
Is all the networking events and our definition of a procedure in the incident Bang.
This has its advantages, we may be able to better write a thread to manage reception and transmission.
Now speaking about a complete port model.
Port completed
In fact, a complete port is a queue informed by the operating system have already been completed overlapping I / O requests notice
Add to them. When an I / O operation Once completed, the operation could be a result of thread processing workers
Will receive a notice. And the socket is created, they can at any time with a complete port clearance
Together.
Steps:
1, the completion of the creation of a space port;
2, the local machine by the number of CPU;
3, open CPU * 2 of threads (also known as thread pool), are all waiting for the completion of the port completed packets;
4, the monitor to create TCP socket, the state will use the incident to create eavesdropping thread;
5, when someone entered the connection, will be kept to a Client socket our own definition of the key button,
And bring it with us to create a complete port association;
6, and the use of WSARecv WSASend function drop some requests, which is the use of overlapping I / O;
7, repeat 5-6;
Note: 1, overlapping I / O mode, the receiving and sending data packets, must request this is a drop
They feature of this architecture
Of course, the completion of port approach, is not direct use WSARecv and WSASend function request
The drop boxes. Instead use the ReadFile, Write the way
2, the use of the port completed within the system models, so long as we must call on the order of
Can be completed.
3, complete port is used in such circumstances, there are tens of thousands of users connected, it can
Performance will not guarantee lower.
# Include <winsock2.h>
# Include <windows.h>
# Include <stdio.h>
# Define PORT 5150
# Define DATA_BUFSIZE 8192
/ / Key items
Typedef struct
(
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer [DATA_BUFSIZE];
DWORD BytesSEND;
DWORD BytesRECV;
) PER_IO_OPERATION_DATA * LPPER_IO_OPERATION_DATA;
Typedef struct
(
SOCKET Socket;
) PER_HANDLE_DATA * LPPER_HANDLE_DATA;
DWORD WINAPI ServerWorkerThread (LPVOID CompletionPortID);
Void main (void)
(
SOCKADDR_IN InternetAddr;
SOCKET Listen;
SOCKET Accept;
HANDLE CompletionPort;
SYSTEM_INFO SystemInfo;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
Int i;
DWORD RecvBytes;
DWORD Flags;
DWORD ThreadID;
WSADATA wsaData;
DWORD Ret;
If ((Ret = WSAStartup (0×0202, & wsaData))! = 0)
(
Printf ( "WSAStartup failed with error% d \ n", Ret);
Return;
)
/ / Open an empty port completed
If ((CompletionPort = CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)
(
Printf ( "CreateIoCompletionPort failed with error:% d \ n", GetLastError ());
Return;
)
/ / Determine how many processors are on the system.
GetSystemInfo (& SystemInfo);
/ / Open the cpu 2 times the number of threads
For (i = 0; i <SystemInfo.dwNumberOfProcessors * 2; i + +)
(
HANDLE ThreadHandle;
/ / Create a server worker thread and pass the completion port to the thread.
If ((ThreadHandle = CreateThread (NULL, 0, ServerWorkerThread, CompletionPort,
0, & ThreadID)) == NULL)
(
Printf ( "CreateThread () failed with error% d \ n", GetLastError ());
Return;
)
/ / Close the thread handle
CloseHandle (ThreadHandle);
)
/ / Open a server socket
If ((Listen = WSASocket (AF_INET, SOCK_STREAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
(
Printf ( "WSASocket () failed with error% d \ n", WSAGetLastError ());
Return;
)
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl (INADDR_ANY);
InternetAddr.sin_port = htons (PORT);
If (bind (Listen, (PSOCKADDR) & InternetAddr, sizeof (InternetAddr)) == SOCKET_ERROR)
(
Printf ( "bind () failed with error% d \ n", WSAGetLastError ());
Return;
)
If (listen (Listen, 5) == SOCKET_ERROR)
(
Printf ( "listen () failed with error% d \ n", WSAGetLastError ());
Return;
)
/ / Begin to receive from the client connections
While (TRUE)
(
If ((= Accept WSAAccept (Listen, NULL, NULL, NULL, 0)) == SOCKET_ERROR)
(
Printf ( "WSAAccept () failed with error% d \ n", WSAGetLastError ());
Return;
)
/ / Create a key for the preservation of the client's information, send users to receive overlapping structure,
/ / Used to have a buffer
If ((PerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc (GPTR,
Sizeof (PER_HANDLE_DATA))) == NULL)
(
Printf ( "GlobalAlloc () failed with error% d \ n", GetLastError ());
Return;
)
/ / Associate the accepted socket with the original completion port.
Printf ( "% d connected Socket number \ n", Accept);
PerHandleData-> Socket = Accept;
/ / And that we completed the creation of the port association, it will be critical with the completion of a designated port association
If (CreateIoCompletionPort ((HANDLE) Accept, CompletionPort, (DWORD) PerHandleData,
0) == NULL)
(
Printf ( "CreateIoCompletionPort failed with error% d \ n", GetLastError ());
Return;
)
/ / Sending a receiver, receiver need to use this function to a reception for delivery
If ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc (GPTR, sizeof (PER_IO_OPERATION_DATA))) == NULL)
(
Printf ( "GlobalAlloc () failed with error% d \ n", GetLastError ());
Return;
)
ZeroMemory (& (PerIoData-> Overlapped), sizeof (OVERLAPPED));
PerIoData-> BytesSEND = 0;
PerIoData-> BytesRECV = 0;
PerIoData-> DataBuf.len = DATA_BUFSIZE;
PerIoData-> DataBuf.buf = PerIoData-> Buffer;
Flags = 0;
If (WSARecv (Accept, & (PerIoData-> DataBuf), 1, & RecvBytes, & Flags,
& (PerIoData-> Overlapped), NULL) == SOCKET_ERROR)
(
If (WSAGetLastError ()! = ERROR_IO_PENDING)
(
Printf ( "WSARecv () failed with error% d \ n", WSAGetLastError ());
Return;
)
)
)
)
/ / Work thread
DWORD WINAPI ServerWorkerThread (LPVOID CompletionPortID)
(
HANDLE CompletionPort = (HANDLE) CompletionPortID;
DWORD BytesTransferred;
LPOVERLAPPED Overlapped;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
DWORD SendBytes, RecvBytes;
DWORD Flags;
While (TRUE)
(
/ / Port is complete news to the
If (GetQueuedCompletionStatus (CompletionPort, & BytesTransferred,
(LPDWORD) & PerHandleData (LPOVERLAPPED *) & PerIoData, INFINITE) == 0)
(
Printf ( "GetQueuedCompletionStatus failed with error% d \ n", GetLastError ());
Return 0;
)
/ / It be that some people withdrew from the
If (BytesTransferred == 0)
(
Printf ( "Closing socket% d \ n", PerHandleData-> Socket);
If (closesocket (PerHandleData-> Socket) == SOCKET_ERROR)
(
Printf ( "closesocket () failed with error% d \ n", WSAGetLastError ());
Return 0;
)
GlobalFree (PerHandleData);
GlobalFree (PerIoData);
Continue;
)
/ /
If (PerIoData-> BytesRECV == 0)
(
PerIoData-> BytesRECV = BytesTransferred;
PerIoData-> BytesSEND = 0;
)
Else
(
PerIoData-> BytesSEND + = BytesTransferred;
)
If (PerIoData-> BytesRECV> PerIoData-> BytesSEND)
(
/ / Post another WSASend () request.
/ / Since WSASend () is not gauranteed to send all of the bytes requested,
/ / Continue posting WSASend () calls until all received bytes are sent.
ZeroMemory (& (PerIoData-> Overlapped), sizeof (OVERLAPPED));
PerIoData-> DataBuf.buf = PerIoData-> Buffer + PerIoData-> BytesSEND;
PerIoData-> DataBuf.len = PerIoData-> BytesRECV - PerIoData-> BytesSEND;
If (WSASend (PerHandleData-> Socket, & (PerIoData-> DataBuf), 1, & SendBytes, 0,
& (PerIoData-> Overlapped), NULL) == SOCKET_ERROR)
(
If (WSAGetLastError ()! = ERROR_IO_PENDING)
(
Printf ( "WSASend () failed with error% d \ n", WSAGetLastError ());
Return 0;
)
)
)
Else
(
PerIoData-> BytesRECV = 0;
/ / Now that there are no more bytes to send post another WSARecv () request.
Flags = 0;
ZeroMemory (& (PerIoData-> Overlapped), sizeof (OVERLAPPED));
PerIoData-> DataBuf.len = DATA_BUFSIZE;
PerIoData-> DataBuf.buf = PerIoData-> Buffer;
If (WSARecv (PerHandleData-> Socket, & (PerIoData-> DataBuf), 1, & RecvBytes, & Flags,
& (PerIoData-> Overlapped), NULL) == SOCKET_ERROR)
(
If (WSAGetLastError ()! = ERROR_IO_PENDING)
(
Printf ( "WSARecv () failed with error% d \ n", WSAGetLastError ());
Return 0;
)
)
)
)
)
Tags: java socket, Socket






