The most streamlined IOCP package

Source: Internet
Author: User

The most streamlined IOCP package, DELPHI XE8 directly compiled through. Winsock2.pas is the use of Delphi, I believe XE7 can also compile, or xe6,xe5 can also.

Winsock2.pas, I have seen countless versions of the version of the Winsock 2 API method parameters of the data types are actually different, the use of various people encapsulated Winsock2.pas source code should be adjusted accordingly,

Otherwise can not be compiled through, I think it is the most reliable use of Delphi official.

To be used in practical applications, it is also necessary to carry out "sticky packet processing".

I am under the Delphi XE8 test OK.

Unit Unit1;

Interface

Uses
Winsock2, Windows, Messages, sysutils, variants, Classes, Graphics, Controls, Forms,
Dialogs, Stdctrls, Extctrls;

Const
buf_size=1024;

Type
Single IO data structure
Lper_io_data = ^tper_io_data;
Tper_io_data = Packed record
overlapped:wsaoverlapped;
Databuf:wsabuf;
Buf:array [0..buf_size-1] of Ansichar;
Sendbytes:dword;
Recvbytes:dword;
End

Data structure of the handle
Lper_handle_data = ^tper_handle_data;
Tper_handle_data = Packed record
Socket:tsocket;
End

Tlistenthread = Class (TThread)
Private
Protected
Procedure Execute;override;
Public
Constructor Create;
End

TForm1 = Class (Tform)
Memo1:tmemo;
Procedure Formcreate (Sender:tobject);
Private
{Private declarations}
Public
{Public declarations}
End

Var
Form1:tform1;
Serversocket:tsocket;

Implementation

{$R *.DFM}

Worker threads
function Workthread (completionportid:pointer):D word; stdcall;
Var
Completionport:thandle;
Bytestransferred:dword;
Perhandledata:lper_handle_data;
Periodata:lper_io_data;
Flags:dword;
Recvbytes:dword;
Begin
completionport:= Thandle (Completionportid);

While True does
Begin
Gets the completion status of the queue on the completion port
GetQueuedCompletionStatus (Completionport, bytestransferred, Ulong_ptr (Perhandledata), POverlapped (PerIOData), INFINITE);
Determine whether the data is sent from the client or the server
If periodata.recvbytes = 0 Then
Begin
Periodata.recvbytes:= bytestransferred;
periodata.sendbytes:= 0;
End Else
periodata.sendbytes:= periodata.sendbytes + bytestransferred;

If periodata.recvbytes > Periodata.sendbytes Then
Begin
ZeroMemory (@ (periodata.overlapped), SizeOf (wsaoverlapped));
periodata.databuf.buf:= periodata.buf + periodata.sendbytes;
Periodata.databuf.len:= periodata.recvbytes-periodata.sendbytes;

It is unsafe to display the received data, and it is an example:)
Form1.Memo1.Lines.Add (String (periodata.buf));
End

Resetting data
periodata.recvbytes:= 0;
Periodata.databuf.len:= buf_size;
periodata.databuf.buf:= @PerIOData. buf;

Re-delivery
WSARecv (Perhandledata.socket, @ (PERIODATA.DATABUF), 1, recvbytes, Flags,
@ (periodata.overlapped), nil);
End
End

{Tworkthread}

Constructor Tlistenthread.create;
Begin
Inherited Create (False);
Freeonterminate:= True;
End

Procedure Tlistenthread.execute;
Var
Wsdata:twsadata;
Completionport:thandle;
Si:tsysteminfo;
Idx:integer;
Threadid:dword;
localaddr:sockaddr_in;
CLIENTADDR:SOCKADDR;
Clientsocket:tsocket;

Per_handle_data:lper_handle_data;
Per_io_data:lper_io_data;

Recvbytes:dword;
Flags:dword;
Begin

//Initialize Winsock
WSAStartup ($202, wsdata);
//Create completion Port
completionport:= CreateIoCompletionPort (invalid_ Handle_value, 0, 0, 0);
//number of worker threads created based on number of processors
GetSystemInfo (SI);
for IDX: = 1 to Si.dwnumberofprocessors do
//create worker threads, and pass the completion port handle to the thread
CreateThread (nil, 0, @WorkThread, Pointer (Completionport), 0, ThreadID);
//Create a listening socket
Serversocket:= WSASocket (Af_inet, Sock_stream, ipproto_tcp, nil, 0, wsa_flag_overlapped);
//Set parameters for Localaddr
localaddr.sin_family:= af_inet;//ipv4 family
Localaddr.sin_addr. S_addr:= inaddr_any;//here can not write inet_addr (' 127.0.0.1 '), otherwise will bind failed, not clear what is the reason;
localaddr.sin_port:= Htons (8000)//host to net short, host byte order to network byte order
//Bind the IP address of the machine, port, first set the LOCALADDR parameters before binding
Bind (ServerSocket, sockaddr (LOCALADDR), SizeOf (LOCALADDR));
//Start listening
Listen (ServerSocket, 5);

While not Terminated do
Begin
clientsocket:= wsaaccept (ServerSocket, @ClientAddr, nil, nil, 0);
Create a variable for the TPER_HANDLE_DATA structure save client socket
per_handle_data:= Lper_handle_data (GlobalAlloc (Gptr, SizeOf (Tper_handle_data)));
Per_handle_data. Socket:= Clientsocket;
Associating the completion port with the client socket
CreateIoCompletionPort (Clientsocket, Completionport, Ulong_ptr (Per_handle_data), 0);
Creating variables for Tper_io_data structures, associating WSARECV functions
per_io_data:= Lper_io_data (GlobalAlloc (Gptr, SizeOf (Tper_io_data)));
ZeroMemory (@PER_IO_DATA. Overlapped, SizeOf (wsaoverlapped));
Per_io_data. sendbytes:= 0;
Per_io_data. recvbytes:= 0;
Per_io_data. Databuf.len:= buf_size;
Per_io_data. Databuf.buf:= @PER_IO_DATA. Buf;

WSARecv (Clientsocket, @ per_io_data. DATABUF), 1, Recvbytes,
Flags, @ (per_io_data. Overlapped), nil);
End
End


Procedure Tform1.formcreate (Sender:tobject);
Begin
Creating a listener thread
Tlistenthread.create ();
End


End.

The most streamlined IOCP package

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.