Home > Back-end >  TServerSocket use the receiving data, found a packet loss, is losing the last data
TServerSocket use the receiving data, found a packet loss, is losing the last data

Time:09-17

Everyone a great god, and to ask, TServerSocket use this when receiving data, the last time data can be received, sometimes sometimes don't get, don't know what is the problem of data or TServerSocket didn't handle
 
Void __fastcall TForm1: : srvrsckt1ClientRead (TObject * Sender,
TCustomWinSocket * Socket)
{
//void * Buffer;
Char * c_data=https://bbs.csdn.net/topics/new char [Socket -> ReceiveLength () + 1);
AnsiString s_temp;
TMemoryStream * stream=new TMemoryStream ();
Stream - & gt; SetSize (Socket - & gt; ReceiveLength ());
Stream - & gt; The Position=0;
The Socket - & gt; ReceiveBuf (stream - & gt; The Memory, the Socket - & gt; ReceiveLength ());
Stream - & gt; Read (c_data, stream - & gt; The Size);
//the stream - & gt; SaveToFile (" 1. TXT ");
Mmo1 - & gt; Lines - & gt; Add (AnsiString (c_data));
Delete the stream;
The delete c_data;
}

CodePudding user response:

ReceiveBuf to array, array wrote MemoryStream, pay attention to the MemoryStream Position after all finished,
Can first SendText a length of string, such as "L8192", received send flow length L represents the beginning, then send flow SendStream,
Read the if (! BHasLength) reads the length of the string, bHasLength=true, else cycle ReceiveBuf reads flow (when the remaining length & gt; 0), such as 1 k per read, read the flow is too long a time may be there is a problem,

CodePudding user response:

You can have a try, I also just contact TServerSocket,

CodePudding user response:

Loop ReceiveBuf might be appropriate delay when several milliseconds, you can also set a timeout break out of circulation,

CodePudding user response:

To see the

CodePudding user response:

The sender can first SendText a length of string, such as IntToStr (fs - & gt; The Size), Sleep several milliseconds, then send flow SendStream,
When the receiver OnRead,
if(! BHasSize)
Just read the length of the string, bHasSize=true,
The else
Loop ReceiveBuf reads flow (when the remaining length & gt; 0), such as 32 k reading every time, every time ReceiveBuf the return value is the actual number of bytes to read. Or read to 1,

And pay special attention to, OnRead event handler will be reentrant, loop reads the flow in a OnRead function calls, OnRead function will be called to perform again, as long as set a variable, it is ok to encounter this kind of situation directly return,

Can also set a Timer, overtime with variable sign out from the loop reads,

Can use a Memo to debug output:
Size: 119182
Reading...
Remain: 119182
The get: 4096
Remain: 115086
Return
The get: 24576
Remain: 90510
1
the get: -Return
Remain: 90510
The get: 24576
Remain: 65934
The get: 12288
Remain: 53646
Return
The get: 24576
Remain: 29070
Return
The get: 24576
Return
Remain: 4494
The get: 4494
Done!

BCB 6.0 each time the machine debugging ReceiveBuf 24 k, most CB2010 is 8 k, every time two machine LAN debugging ReceiveBuf is generally not more than 8 k,

CodePudding user response:

The sender can first SendText a length of string, such as IntToStr (fs - & gt; The Size), Sleep several milliseconds, then send flow SendStream,
-
This is bad, the need for Sleep between sending twice,
First SendBuf sends a length int, buf mandatory address translation for int *,

CodePudding user response:

@ ooolinux first to thank you for your answer, I'll in srvrsckt1ClientRead event loop read, send here I can't control, because the equipment is automatically sent, don't know how the device is sending mechanism, here I can control my side received, thank you again,

CodePudding user response:

Before sending, receiving flow to send, receive stream length, is also one of the more common practice,

CodePudding user response:

Send large flow, using ReceiveBuf receive only one must be incomplete, because every time ReceiveBuf to receive the quantity is limited,

CodePudding user response:

If you send first SendText a length of string, such as IntToStr (fs - & gt; The Size), Sleep several milliseconds, then send SendStream flow; When receiving the middle also want to Sleep, but the number of milliseconds less than send Sleep among the number of milliseconds,
If you don't Sleep, the data is easy to string together lead to receive error,

But send an int length can use SendBuf, need not Sleep, when receiving a little bit complicated code,

CodePudding user response:

Can take the way one way:
The client sends "getfile filename" string; Open the file on the server flow, the size of the send flow information;
The client receives the flow, the size of the send the "ready" string; The server sends flow;
The client (loop) receiving flow,

CodePudding user response:

Void __fastcall TForm1: : srvrsckt1ClientRead (TObject * Sender,
TCustomWinSocket * Socket)
{
//void * Buffer;
Char * c_data=https://bbs.csdn.net/topics/new char [Socket -> ReceiveLength () + 1);
AnsiString s_temp;
TMemoryStream * stream=new TMemoryStream ();
Stream - & gt; SetSize (Socket - & gt; ReceiveLength ());
Stream - & gt; The Position=0;
The Socket - & gt; ReceiveBuf (stream - & gt; The Memory, the Socket - & gt; ReceiveLength ());
Stream - & gt; Read (c_data, stream - & gt; The Size);
//the stream - & gt; SaveToFile (" 1. TXT ");
Mmo1 - & gt; Lines - & gt; Add (AnsiString (c_data));
Delete the stream;
The delete c_data;
}

CodePudding user response:

Didn't try INDY? The control is simple to use,
  • Related