Currently, the iocp function still has the server data returned.
Or use netty. The call to the data returned by netty is contenxt. Write (<tobject> OBJ). In this way, the OBJ object is sent to the client.
1. encode the returned object into a buffer.
2. Transfer through socket.
>>>>>>>>>>>>>
Below I post the process of returning data.
procedure TClientContext.writeObject(const pvDataObject:TObject);var lvOutBuffer:TBufferLink;begin lvOutBuffer := TBufferLink.Create; try TContextFactory.instance.FEncoder.Encode(pvDataObject, lvOutBuffer); TIOCPTools.SendBuffer(self.FSocket, lvOutBuffer); finally lvOutBuffer.Free; end;end;
During data processing, I tried to call this code.
Procedure tclientcontext. datareceived (const pvdataobject: tobject); var lvjsonstream: tjsonstreamobject; lvfile: string; begin lvjsonstream: = tjsonstreamobject (pvdataobject); // the client sends the file if lvjsonstream. JSON. I ['cmdindex '] = 102 then begin lvfile: = extractfilepath (paramstr (0) + 'tempfile \'; forcedirectories (lvfile); lvfile: = lvfile + lvjsonstream. JSON. s ['file']; tmemorystream (lvjsonstream. stream ). position: = 0; tmemorystream (lvjsonstream. stream ). savetofile (lvfile); End else begin // return data writeobject (lvjsonstream); end; tlogclientwrapper. loginfo (lvjsonstream. JSON. asjson (true); end;
In the iocp work thread, if the data is sent completely, the memory block is recycled.
End else if periodata. io_type = io_type_send then begin // send complete data <wsasend> complete // reclaim data block tiodatamempool. instance. givebackiodata (periodata); end;
Tiocptools. sendbuffer code
Unit iocptools; interfaceuses ubuffer, jwawinsock2, umempool, windows; const io_type_accept = 1; io_type_recv = 2; io_type_send = 3; // send data type tiocptools = Class (tobject) public class procedure sendbuffer (pvsocket: tsocket; const oubuf: tbufferlink); end; implementationclass procedure tiocptools. sendbuffer (pvsocket: tsocket; const oubuf: tbufferlink); var lvidata: lpper_io_operation_data; lvret: Cardinal ; Begin while oubuf. validcount> 0 do begin lviodata: = tiodatamempool. instance. borrowiodata; lvidata. io_type: = io_type_send; // here I changed the size of the memory block, and the length of each sending cannot exceed the SET SIZE OF THE memory block. If the data is insufficient
// Databuf. Len specifies the size of the memory block to be sent. The memory block size needs to be restored when it is recycled. Lviodata. databuf. len: = oubuf. readbuffer (lviodata. databuf. buf, lviodata. databuf. len); If (wsasend (pvsocket, @ lvidata. databuf, 1, lviodata. workbytes, lvidata. workflag, @ lvidata ^, nil) = socket_error) then begin lvret: = getlasterror (); // overlapped Io. It is normal to see error_io_pending, // indicates that the data has not been received, if data is received, getqueuedcompletionstatus returns the value if (lvret <> error_io_pending) then begin closesocket (pvsocket); break; end.
// Encoder code, responsible for converting the sent object into a stream
Unit ujsonstreamencoder; interfaceuses uiocpdecoder, ubuffer, classes, superobject, sysutils; Type tjsonstreamencoder = Class (tiocpencoder) public /// <summary> /// encode the object to be sent /// </Summary> /// <Param name = "pvdataobject"> encode the object </ param> // <Param name = "oubuf"> encoded data </param> procedure encode (pvdataobject: tobject; const oubuf: tbufferlink); override; end; implementationuses ujsonstreamobject, windows; Procedure tjsonstreamencoder. encode (pvdataobject: tobject; const oubuf: tbufferlink); var lvjsonstreamobject: tjsonstreamobject; lvjsonlength: integer; lvstreamlength: integer; sdata: string; lvstream: tstream; lvtempbuf: pansichar; begin if pvdataobject = nil then exit; lvjsonstreamobject: = tjsonstreamobject (pvdataobject); sdata: = lvjsonstreamobject. JSON. asjson (true); lvjsonlength: = length (sdata); lvstream: = lvjsonstreamobject. stream; oubuf. addbuffer (@ lvjsonlength, sizeof (lvjsonlength); If lvstream <> nil then begin lvstreamlength: = lvstream. size; end else begin lvstreamlength: = 0; end; oubuf. addbuffer (@ lvstreamlength, sizeof (lvstreamlength); // JSON bytes oubuf. addbuffer (@ sdata [1], lvjsonlength); If lvstreamlength> 0 then begin // stream bytes getmem (lvtempbuf, lvstreamlength); try lvstream. position: = 0; lvstream. readbuffer (lvtempbuf ^, lvstreamlength); oubuf. addbuffer (lvtempbuf, lvstreamlength); finally freemem (lvtempbuf, lvstreamlength); end.
>>>>> I have posted all the key code. Demo is not provided this time. Leave a message if necessary
The next learning topic is a demo of stress testing.