Comparison of the three UDP Communication implementation methods in C ++ builder from the findheart blog
Comparison of Three UDP Communication implementation methods under the keyword C ++ Builder
Source
This article mainly discusses data acceptance:
1. nmudp Control
This control is easy to use. Set the listening port and then respond to the datareceived event. For example:
Void _ fastcall tmoniter: nmudpdatareceived (tcomponent * sender,
Int numberbytes, ansistring fromip, int port)
{
/* Use a flag variable to control whether to perform the required operations after the control is trusted */
If (recvflag)
{
Int RL;
/* Memory used to receive data */
Unsigned char rbuf [1024*9];
/* control readbuffer method, which stores the received data to rbuf */
nmudp-> readbuffer (rbuf, sizeof (rbuf), rl );
/* string end */
rbuf [RL] = 0;
/* stream is a pre-defined file pointer */
If (stream! = NULL)
{< br>/* compile the dolog function to write the received data to the log file */
dolog (false, rbuf, rl );
}< BR >}< br> this control is easy to use and efficient, but only supports 2 k buffering, therefore, the 9k memory opened above is redundant. Due to the 2 k restriction, I had to discard the control in the project.
2. idudpserver Control
The usage method is similar to that of nmudp. You can respond to the udpread event. For example: (see note 1)
Void _ fastcall tmoniter: idudpserver1udpread (tobject * sender,
Tstream * aData, tidsockethandle * abinding)
{
If (recvflag)
{
Int R1;
Unsigned char rbuf [1024*9];
R1 = aData-> size;
/* The received data is stored in the data stream aData and read them to rbuf */
AData-> Read (rbuf, R1 );
Rbuf [R1] = 0;
If (stream! = NULL)
{
Dolog (false, rbuf, R1 );
}
}
}
This control supports 9 K buffering, but the efficiency ...... I need to receive more than 150 1 K data packets in one second and decode them and display them row by row in the stringgrid. Although it is a waste of time to depict the stringgrid, The idudpserver is still unsatisfactory.
3. Return to nature-socket
The two controls cannot meet my needs, so I can only look back at the underlying socket (my C is not good, but this method is still not very clear, so there are few annotations, but throughCode).
First define these three things:
Socket sock
Wsadata
Sockaddr_in sockaddr
Then perform socket initialization where you need to start receiving messages. Here I use a button:
Int result;
Word wversionrequested;
Wversionrequested = makeword (1, 1 );
If (result = wsastartup (wversionrequested, & wsadata ))! = 0)
{
Application-> messageboxa ("socket initial error", "error", mb_ OK );
Wsacleanup ();
Return;
}
Memset (& sockaddr, 0, sizeof (sockaddr ));
/* Set the port number */
Sockaddr. sin_port = htons (3000 );
Sockaddr. sin_family = af_inet;
Sockaddr. sin_addr.s_un.s_addr = htonl (inaddr_any );
Sock = socket (af_inet, sock_dgram, 0 );
If (sock = invalid_socket)
{
Application-> messageboxa ("socket open failed", "error", mb_ OK );
Wsacleanup ();
Return;
}
Result = BIND (sock, (lpsockaddr) & sockaddr, sizeof sockaddr );
If (result = socket_error)
{
Application-> messageboxa ("BIND error", "error", mb_ OK );
Wsacleanup ();
Return;
}
/* The self-Write function getfileready opens a log file and waits for the recorded data */
If (! Getfileready ())
{
Wsacleanup ();
Return;
}
/* Clear the stringgrid editing area */
Sglog-> rowcount = 2;
Sglog-> rows [1]-> clear ();
Sglog-> cells [0] [1] = "1 ";
Linecount = 1;
/* Start the thread and accept data */
Recvflag = true;
Tudpr = new tudpr (true );
Tudpr-> resume ();
}
Tudpr is a trusted thread. Its Class is defined as follows:
Class tudpr: Public tthread
{
PRIVATE:
Protected:
Void _ fastcall execute ();
Public:
_ Fastcall tudpr (bool createsuincluded );
};
The complete processing in the thread is as follows:
# Include <VCL. h>
# Pragma hdrstop
# Include <Winsock. h>
# Include "tudpr. H"
# Include "monitor. H"
Extern int m_sendrcvflag;
Extern socket sock;
Extern wsadata;
Extern sockaddr_in sockaddr;
# Pragma package (smart_init)
_ Fastcall tudpr: tudpr (bool createsu0000ded)
: Tthread (createsuincluded)
{
}
Void _ fastcall tudpr: Execute ()
{
Int result;
Unsigned char rbuf [sndrcvdatalen];
/* Receive data when the trusted flag variable is true */
While (recvflag)
{
Result = recvfrom (sock,
Rbuf,
Sndrcvdatalen,
0,
Null,
Null
);
If (! Recvflag)
{
Break;
}
If (result = socket_error)
{
Application-> messageboxa ("receive error", "error", mb_ OK );
Wsacleanup ();
Return;
}
Rbuf [Result] = 0;
/* Refer to dolog comment in 1 */
Moniter-> dolog (false, rbuf, result );
}
}
The third method can meet the requirements in terms of efficiency, but it also requires much trouble to manage the thread.
Author blog: http://blog.csdn.net/findheart;