After watching sockcomp.pas on July 4, I decided to write a client and server with the Socket API and support TCP, UDP protocol, so I will do it, and I am discouraged (have been debugged) Socket API Client: #ifndef udpclientH # define udpclientH # include
} Void __fastcall TLANForm :: FormCreate (TObject * Sender) {:: SendMessage (Prot-> Handle, CB_SETCURSEL, 0,0);} void __fastcall TLANForm :: OnRecv (TMessage & Message) {char buf [4096]; int nLen; struct sockaddr_in from; int nLength = sizeof (struct sockaddr_in); switch (WSAGETSELECTEVENT (Message.LParam)) {case FD_READ: switch (m_Protocol) {case TCP: nLen = recv (m_Socket, buf, 4096,0); if (nLen > 0) {BUF [NLEN] = '/ 0'; txtedit-> text = "Received Length:" String (NLEN) "/ R / N" StrPas (BUF);} Break; Case UDP: Nlen = Recvfrom (m_socket, buf, 4096, 0, (struct sockaddr *) & from, & nlength); if (Nlen> 0) {BUF [NLEN] = '/ 0'; txtedit-> text = "Received Length:" string (STED LENGTH: STRING NLEN) "/ r / n" strPas (buf);} Break;} Break; casser: CLOSESOCKET (M_Socket); Break;}} void __fastcall TLANFORM :: Button1Click (Tobject * sender) {char sztmp [256], buf [4096]; int nsize = 0; uint m_port; ansistring addr; addr = addr-> text.trim (); if (addr.isempty () ) {:: MessageBox (0, "please enter the server ip!", "Error", MB_ok MB_ICONERROR); RETURN;} Unsigned long naddr = inet_addr (addr.c_str ()); if (Naddr == INADDR_NONE) { :: MessageBox (0, "Bad Internet IP!", "Error", MB_ok MB_ICONERROR); RETURN;}
Try {m_port = port-> text.Toint ();} catch (exception & e) {:: messagebox (0, E.Message.c_str (), "error", MB_OK MB_ICONERROR); return;} switch (prot) > Itemindex) {case 0: m_protocol = TCP; Break; case 1: m_protocol = udp; break;} if (txtedit-> text.isempty ()) {:: messagebox (0, "please enter the text you want to send ! "," Error ", MB_ok MB_ICONERROR); return;} file: // initialize Winsocket Wsadata wsadata; :: ZeromeMory (& WSADATA); Word Version = MakeWord (2,0); if (:: WSAStartup (Version, & Wsadata)) {sprintf (Sztmp, "Failed to Initial Winsock Enviroment!, Error NO:% D", :: wsagetlasterror (); return;}
file: // Obtain the active connection char ComputerName [255]; gethostname (ComputerName, 255); struct hostent * he = gethostbyname (ComputerName); if (he!) {sprintf (szTmp, "Failed to get information to host!" , "Error", MB_OK MB_ICONERROR); :: WSACleanup (); return;} file: // create new socket m_Socket = INVALID_SOCKET; switch (m_Protocol) {case TCP: m_Socket = socket (AF_INET, SOCK_STREAM, 0); break Case udp: m_socket = socket (AF_INET, SOCK_DGRAM, 0); Break;} if (m_socket == invalid_socket) {sprintf (sztmp, "failed to create a new socket!, Error no:% d", :: wsagetlasterror )) ;: MessageBox (0, sztmp, "error", MB_ok MB_ICONEROR); :: wsacleanup (); return;} file: // bind socket structure; unsigned long nclient; memcpy (& nclient, he-> H_addr_list [0], sizeof (int)); if (nclient == inaddr_none) {sprintf (sztmp, "failed to obtain the local machine's ip!", "error", MB_OK MB_ICONERROR); :: MessageBox (0, sztmp " Error ", MB_OK MB_ICONERROR); CloseSocket (M_Socket) ;: wsacleanup (); return;} client.sin_family = af_INET; client.sin_port = 0; client.sin_addr.s_un.s_addr = (int) nclient; if (bind) (M_Socket, (Struct SockAddr *) & Client, Sizeof (SZTMP, "Failed to Bind Socket!", "Error", MB_OK MB_ICONERROR); CloseSocket (m_socket) ;:: wsacleanup (); Return;} file: // connect socket structure sockaddr_in to; to; to.sin_family = af_INET; to.SIN_PORT = HTONS (M_Port); to.sin_addr.s_un.s_addr = (int) Naddr; fd_set fdset; fd_zero (& fdset);
FD_SET (m_Socket, & FDSET); if (m_Protocol == TCP) {if (connect (m_Socket, (struct sockaddr *) & To, sizeof (struct sockaddr))) {sprintf (szTmp, "Failed to connect the object, error no! :% D ", :: wsagetlasterror ()); :: MessageBox (0, sztmp," error ", MB_OK MB_ICONERROR); CloseSocket (m_socket); :: wsacleanup (); return;} int Nerror = SELECT (1, 0, & fdset, 0, 0); if (Nerror <= 0) {Sprintf (Sztmp, "Failed to SELECT Socket!, Error NO:% D", :: Wsagetlasterror (); CloseSocket (m_socket); :: WSacleanup ();}}} File: // send data int Nlen = txtEDit-> text.length (); if (Nlen> 4096) {sprintf (sztmp, "The buffer is to scheve, it shoud not be more, IT SHOUD NOT BE Than 4096 Bytes! "); :: MessageBox (0, SZTMP," Error ", MB_OK MB_ICONERROR); CloseSocket (m_socket) ;: wsacleanup (); return;} strncpy (buf, txtedit-> text.c_str () , NLEN); Switch (m_protocol) {Case TCP: nsize = send (m_socket, buf, nlen, 0); file: // showMessage (nsize); Break; Case UDP: nsize = sendto (m_socket, buf, nlen, 0, (struct socmeddr *) & to, sizeof (struct sockaddr)); file: // showMessage (nsize); Break;
} F (:: wsaasyncselect (m_socket, handle, wm_sock, fd_read | fd_close)) {sprintf (sztmp, "failed to register socket evenet!, Error no:% d", :: wsagetlasterror ()); :: messagebox (0 , SZTMP, "Error", MB_OK MB_ICONERROR); CloseSocket (m_socket) ;: wsacleanup (); return;}} void __fastcall tlanform :: formDestroy (Tobject * sender) {CloseSocket; :: wsacleanup () ;: wsacleanup () }
Socket API Server: .h File # i i i cc
void __fastcall CreateListenSocket (); void __fastcall SetListenSocket (); void __fastcall BindListenSocket (); void __fastcall ListenSocket (); public: __fastcall TListenThread (PROTO m_ProtocolA, UINT m_PortA, bool CreateSuspended); virtual __fastcall ~ TListenThread (); protected: virtual void __fastcall Execute ();}; extern PACKAGE TPSTNForm * PSTNForm; # endif.cpp File # include
} file: // ***************************** Class TlistentHread ********************* ************************************************* __ FastCall Tlistenthread :: Tlistenthread (Proto M_Protocola, UINT m_PortA, bool CreateSuspended): TThread (FALSE) {m_Socket = INVALID_SOCKET; m_Port = m_PortA; m_Protocol = m_ProtocolA; szTmp [0] = '/ 0'; :: ZeroMemory (& wsaData, sizeof (WSAData)); :: ZeroMemory (& server , sizeof (struct sockaddr_in)); FreeOnTerminate = TRUE;. // Automatically delete while terminating} __ fastcall TListenThread :: ~ TListenThread () {closesocket (m_Socket); :: WSACleanup (); m_Socket = INVALID_SOCKET; m_Port = 0; m_Protocol = TCP; sztmp [0] = '/ 0';:: ZeromeMory (& WSADATA); :: ZeromeMory);} void __fastcall tlistenthread :: doerror () {i (m_socket ! = INVALID_SOCKET) closesocket (m_Socket); WSACleanup (); return;} void __fastcall TListenThread :: InitSocket () {WORD version = MAKEWORD (2,0); if (:: WSAStartup (version, & wsaData)) {sprintf (szTmp , "Failed to intiailize SOC KET, ERROR NO:% D ", :: wsagetlasterror ()); :: MessageBox (0, Sztmp," Error ", MB_OK MB_ICONERROR); doerror (); return;}} void __fastcall tlistenthread :: createlistensocket ()} switch (m_Protocol) {case UDP: m_Socket = socket (AF_INET, SOCK_DGRAM, 0); break; case TCP: m_Socket = socket (AF_INET, SOCK_STREAM, 0); break; default: sprintf (szTmp, "Error protocol!"); :: MessageBox (0, Sztmp, "Error", MB_OK MB_ICONERROR); doerror (); break;} if (m_socket == invalid_socket) {sprintf (sztmp, "failed to create socket!");
:: MessageBox (0, szTmp, "Error", MB_OK MB_ICONERROR); DoError (); return;}} void __fastcall TListenThread :: SetListenSocket () {server.sin_family = AF_INET; server.sin_port = htons (m_Port); server .sin_addr.S_un.S_addr = INADDR_ANY; int NewOpenType = SO_SYNCHRONOUS_NONALERT; if (setsockopt (INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *) & NewOpenType, 4)) {sprintf (szTmp, "Set socket option error, error no:% d" :: wsagetlasterror ()); :: MessageBox (0, sztmp, "error", MB_OK MB_ICONERROR); doerror (); return;}} void __fastcall tlistenthread :: bindlistensocket () {if (bind (m_socket, (sockaddr) *) & server, sizeof (Struct SockAddr_in))) {sprintf (Sztmp, "Failed to Bind Socket, Error NO:% D", :: WsageTlasterror ()); :: MessageBox (0, Sztmp, "Error", MB_OK MB_ICONERROR); doerror (); Return;}
} void __fastcall tlistenthread :: listensocket () {i ((m_socket, somaxconn) {sprintf (sztmp, "listen error, error no:% d", :: wsagetlasterror ()); :: messagebox (0, sztmp, "Error", MB_OK MB_ICONERROR); DoError (); return;} file: // Determine whether there is any connection FD_ZERO (& FDS); FD_SET (m_Socket, & FDS);} void __fastcall TListenThread :: Execute () {char buf [4096]; struct sockaddr_in from; file: // for udp int Nlen = sizeof (from), nsize = 0; file: // for udp initsocket (); createlistensocket (); setListensocket (); bindlistensocket (); f ( M_Protocol == UDP) {While (! Terminated) {Int nsize = recvfrom (m_socket, buf, 4096, 0, (strunt sockaddr *) & from, & nlen); if (nsize> 0) {BUF [nsize] = '/ 0 '; Pstnform-> Memo1-> Lines-> Add ("received length:" string (nsize)); pstnform-> memo1-> lines-> add ("received:" strPas (buf)); :: SLEEP (100); sendto (m_socket, buf, nsize, 0, (struct socketdr *) & from, sizeof (struct sockaddr_in);} Else Return;
}} Listensocket (); struct sockaddr_in client; int nlength = sizeof (struct socketdr_in); while (! Terminated) {Int Nerror = SELECT (1, & fds, 0,0,0); if (Nerror <= 0) Terminate ); SOCKET m_AcceptSocket = accept (m_Socket, (struct sockaddr *) & client, & nLength); if (m_AcceptSocket == INVALID_SOCKET) {sprintf (szTmp, "Failed to execute accept, error no:% d", :: WSAGetLastError ()) ; :: MessageBox (0, szTmp, "Error", MB_OK MB_ICONERROR); DoError (); Terminate (); return;} TCommunication * pCThread = new TCommunication (m_AcceptSocket, FALSE); pCThread-> Terminate (); pCThread- > WaitFor ();}} file: // ********************** PSTNFORM ************************* ****************************** / / __ fastcall TPSTNFORM :: TPSTNFORM (TComponent * Owner): TFORM (Owner) {} void __fastcall TPSTNForm :: Button1Click (TObject * Sender) {Close ();} void __fastcall TPSTNForm :: Button2Click (TObject * Sender) {if (pThread) {pThread-> Suspend (); pThread-> Terminate (); dele TE pthread; pthread = 0;} uint m_port; try {m_port = port-> text.Toint ();} catch (exception & e) {:: messagebox (0, E.MESSAGE.C_STR (), "error", MB_OK MB_ICONERROR); return;} PROTO m_Protocol; switch (Prot-> ItemIndex) {case 0: m_Protocol = TCP; break; case 1: m_Protocol = UDP; break; default: break;} pThread = new TListenThread (m_Protocol, m_Port, File: // pthread-> terminate ();} void __fastcall tpstnform :: formcall (TOBJECT * Sender) {: seundMessage (prot-> handle, cb_setcursel, 0, 1);}
Void __fastcall tpstnform :: formdestroy (TOBJECT * Sender) {if (pthread) {pthread-> susnd (); pthread-> terminate ();}} The above code, you can use the own needs and for your own application, The data processing is improved. Again, the file appearing in the above code: Prefix this is automatically added by the 9CBS document editor. Everyone see the file: prefix indicates that it is a comment section, this statement, so as not to misunderstand.