Comparison of three UDP communication implementations under C ++ Builder

xiaoxiao2021-03-06  38

Mainly discuss data acceptance: 1.NMUDP control This control is relatively simple, set listener port, then respond to DataReceived events, for example: void __fastcall tmoniter :: nmudpdataareced (tComponent * sender, int numberBytes, Ansistring fromip, INT port) {/ * uses a flag variable control control whether the control is confident * / if (recvflag) {Int rl; / * is used to accept data * / unsigned char RBUF [1024 * 9]; / * The READBUFFER method of the control, stores the received data to RBUF * / NMUDP -> ReadBuffer (RBUF, SIZEOF (RBUF), RL); / * String end * / RBUF [rl] = 0; / * stream is prior definition File pointer * / if (stream! = Null) {/ * self-edog function, write the received data into log file * / DOLOG (False, RBUF, RL);}}} The advantage of this control is simple, efficiency It is relatively high, but only supports 2K buffering, so the 9k memory opened above is redundant. The 2K limit has made me give up this control in the project. 2.IdUDPServer controls to use with NMUDP similar response UDPRead event can be, for example :( Notes Reference 1) void __fastcall TMoniter :: IdUDPServer1UDPRead (TObject * Sender, TStream * AData, TIdSocketHandle * ABinding) {if (recvFlag) {int R1; unsigned char RBUF [1024 * 9]; r1 = adata-> size; / * Accept data is stored in the data stream Adata, read them to RBUF * / adata-> read (RBUF, R1 ); RBUF [R1] = 0; if (stream! = Null) {DOLOG (false, rbuf, r1);}}} This control supports 9k buffering, but efficiency ... I need 1 second to receive 150 1K Many packets and decoded after the progress line is displayed in stringgrid, although it is mainly a waste time for StringGrid, but iDudpserver is still unsatisfactory. 3. Return to nature - Socket two controls can not meet my needs, then I can only consider the bottom Socket (my C is not good, I don't quite understand this method, so I've been very small, but I passed the code. Can guess its functionality). First define these three stones: Socket Sockwsadata WsadataSockAddr_in SockAddr and then initialize Socket initialization where you need to start trusted, 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 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;}

/ * Self-write function getFileReady Open a log file waiting logging data * / if (! GetfileReady ()) {wsacleanup (); return;}

/ * Clean stringgrid editing area * / sglog -> rowcount = 2; sglog -> rows [1] -> CLEAR (); sglog -> cells [0] [1] = "1"; linecount = 1;

/ * Start thread, accept data * / recvflag = true; tudpr = new tudpr (true); tudpr-> resume ();} TUDPR is a thread that is responsible for trusted, and its class is as follows: Class Tudpr: public tthread {private: protected : Void __fastcall execute (); public: __fastcall tudpr (Bool createSuspend);}; integrity within the thread is as follows: #include #pragma hdrstop # include

#include "tudpr.h" #include "monitor.h"

Extern Int m_sendrcvflag; extern socket sock; extern wsadata wsadata; extern sockaddr_in sockaddr;

#pragma package (smart_init)

__fastcall TUDPR :: TUDPR (bool CreateSuspended): TThread (CreateSuspended) {} ​​void __fastcall TUDPR :: Execute () {int result; unsigned char rbuf [SNDRCVDATALEN]; / * variable to receive a flag trusted data * / while (recvFlag true {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; / * Reference 1 DOLOG Note * / Moniter -> DOLOG (false, rbuf, result);}} The third method can be met in efficiency Required, but you need to manage threads, it is also a lot of trouble.

转载请注明原文地址:https://www.9cbs.com/read-66085.html

New Post(0)