Write network communication programs with TSERVERSOCKET, TCLIENTSOCKET in C ++ Builder

zhaozj2021-02-16  44

This article mainly describes how to write a network short packet, file transfer program in C Builder, which can support: 1. Transmission on the LAN. 2. LAN and public transmission (two-way transmission), in the second article I will write a client and server, function, and function in this article with the Socket API. With communication protocol TCP, the client and server use of the server are blocked mode - multithreaded. Client: .h Fileclass ClientThread: public TThread {private: AnsiString File; TClientSocket * ClientSocket; TWinSocketStream * WskStream; protected: void __fastcall Execute (); public: __fastcall ClientThread (AnsiString IPAddr, WORD Port, AnsiString file);

}

.cpp filevoid __fastcall clientthread :: execute () {

// Send Text or SendFile UINT TimeOut = 60000; char buf [4096]; // char IPAddress [32]; // GetIPAddress (IPAddress); // IPAddress WskStream = new TWinSocketStream (ClientSocket-> Socket, TimeOut); if ( FORM1-> CheckBox1-> Checked) // determine WHETER TO Send short pack or send file. {String s = form1-> txtEDit-> text; int txtlen = form1-> txtedit-> text.length (); strncpy (buf , Sc_str (); clientsocket-> Active = true; wskstream-> write ("text / 0", 5); // send text flag wskstream-> Write (ipaddress, 32); // send IP Address WSKSTREAM-> WRITE (BUF, TXTLEN); // Send text string wskstream-> write (buf, txtlen); if (wskstream-> waitfordata) {buf [0] = '/ 0'; flagbuf [0 ] = '/ 0'; ipaddress [0] = '/ 0'; wskstream-> read (flagbuf, 5); wskstream-> read (ipaddress, 32); int nsize = 0; nsize = wskstream-> read (buf , Txtlen; buf [nsize] = '/ 0'; if (! Strpas (buf) .Isempty ()) {SAVELOG ("Received A TE XT! "); SAVELOG (" Client: " StrPas (ipaddress) " / R / NStart Time: " DateTimetostr (now ())); SAVELOG (" Text Content: " StrPas (BUF); Flashwinfo FshInfo ; :: ZeroMemory (& FSHINFO, sizeof (FLASHWINFO)); FSHINFO.cbSize = sizeof (FLASHWINFO); FSHINFO.hwnd = Application-> Handle; FSHINFO.dwFlags = FLASHW_TRAY | FLASHW_CAPTION; FSHINFO.uCount = 10; FSHINFO.dwTimeout = 200 ;: flashwindowex; form1-> recedit-> lines-> add ("

Received Length: " String (nsize)); Form1-> Recedit-> Lines-> Add (" ReceiVed: " StrPas (BUF)); // Savelog (" Client: " StrPas (ipaddress) " / r / NEND TIME: " DateTimetostr (NOW ()));}}} else {Int Nlen; int hfile; int nsize; char path [255]; // path buffer char filename [255]; // filename buffer; char FileExt [5]; // Extension Buffer Char flagbuf [5]; static int Num = 0; Ansistring sfilename = extractFileName (file); for (int K = sfilename.length (); k> 0; k -) {IF (sfilename.substring (k, 1) == ".") {sfilename = sfilename.substring (1, k-1); Break;}} ansistring spath = extractFilePath (file); Ansistring Sextension = extractfileext (file);

STRCPY (filename, sfilename.c_str ()); // filename structure (path, spath.c_str ()); // path struct (fileext, sextension.c_str ()); // extension try {hfile = -1; ClientSocket-> Active = true; hfile = fileopen (file, fly, fly, file, file,); if (hfile! = -1) {nsize = getFileSize ((Handle) hfile, null; // send the flag wskstream-> Write ("File / 0 ", 5); // send the name of directory wskstream-> write (path, 255); // send the filename wskstream-> write (filename, 255); // send the extension of file wskstream-> write FileExt, 5); // Send Client's IP Addresss WSKStream-> Write (iPaddress, 32);

// send the length, 4); // send the data for (; nsize> 0; nsize- = Nlen) {nlen = min ((int) sizeof (buf), nsize); Nlen = FileRead (HFile, BUF, NLEN); if (Nlen <= 0) Break; WSKStream-> Write (buf, nlen);}} fileclose (hfile); // send Completely // Client Is Beginning to Read Data

IF (WSKStream-> WaitFordata) {wskstream-> read (flagbuf, 5);} if (wskstream-> waitfordata (timeout) // Obtain the Directory's name {wskstream-> read (Path, 255);} // If the directory obtained from client doesnot exist, the create it if {createDir (StrPas (Path));} (DirectoryExists (StrPas (Path))!) // Obtain the FileName if (WskStream-> WaitForData (TimeOut)) {WskStream-> Read (FileName, 255);} // Obtain the extension if (WskStream-> WaitForData (TimeOut)) {WskStream-> Read (FileExt, 5);} // Obtain the client's IPAddress if (WskStream-> WaitFordata (Timeout)) {wskstream-> read (iPaddress, 32);} ansistring s = strpas (path) strpas (fileEname) strPas (fileext); buf [0] = '/ 0'; strcpy (buf, s) .c_str ()); While (1) {IF (FileExists (buf)) { S = STRPAS (PATH) STRPAS (FileName) "FileExt); WSPrintf (buf, s.c_str (), NUM); Num ; // Created SUSSCESSFULLY} else break;} hfile = filecreate BUF); if (hfile == - 1) {Application-> MessageBox ("Failed to Create File!", "Error", MB_OK MB_ICONERROR); ClientSocket-> Active = false; delete wskstream; terminate (); return; Savelog ("Received A File:" StrPas (BUF)); Savelog ("Client:"

STRPAS (ipaddress) "/ R / NStart Time:" DateTimetostr (now ())); try {dWord dwtyick = gettickcount (); // Obtain the length if (WSKSTREAM-> WaitFordata (Timeout) {Nlen = WSKStream -> Read (& nsize, 4); if (Nlen! = 4) nsize = 0;} else nsize = 0; // reading data for (; nsize> 0 &&! Terminated; nsize- = Nlen) {if (! Wskstream -> WaitFordata (5000)) {IF (GettickCount () - dwtick Active = false; Break;} nlen = wskstream-> read (buf, sizeof (buf)); dwtyick = gettickcount (); if (NLE) N <= 0) {// Read Error ClientSocket-> Active = false; :: MessageBox (Null, "Read Error, The Thread Has Been Terminated!", "Error", MB_ok | MB_ICONERROR); Break;} // Combine The Data Filewrite (HFILE, BUF, NLEN);} form1-> recedit-> lines-> add ("you got a file from server, Which Was Saved in" StrPas (PATH)); SAVELOG ("Client:" StrPas (ipaddress) "/ R / Nend Time:" DateTimetostr (now ())); Flashwinfo FshInfo;

:: ZeroMemory (& FSHINFO, sizeof (FLASHWINFO)); FSHINFO.cbSize = sizeof (FLASHWINFO); FSHINFO.hwnd = Application-> Handle; FSHINFO.dwFlags = FLASHW_TRAY | FLASHW_CAPTION; FSHINFO.uCount = 10; FSHINFO.dwTimeout = 200; :: FlashWindowEx; FileClose (HFile);} catch (Exception & E) {ClientSocket-> Active = false; MessageBox (0, E.MESSAGE.C_STR (), "Error", MB_ICONERROR);}} catch (Exception & e) {ClientSocket-> Active = false ;:: MessageBox (0, E.MESSAGE.C_STR (), "Error", MB_OK | MB_ICONERROR);} fileclose (hfile);} delete wskstream; // delete clientsocket;}

// begin to send packagevoid __fastcall tform1 :: button1click (TOBJECT * Sender) {INT port; ANSISTRING ADDR

Addr = ipaddr-> text.trim (); if (addr.isempty ()) {ipaddr-> setfocus (); Application-> MessageBox ("please enter the client's address!", "Warning", MB_OK | MB_ICONWARNING); Return;} try {port = clientport-> text.toint ();} catch (e.Message); clientport-> setfocus (); return;} if (checkbox1-> checked) // send Text {if (txtedit-> text.isempty ()) {:: messagebox (0, "please enter!", "Error", MB_OK MB_ICONERROR); RETURN;}

New ClientThread (addr, port, ");} else // send file {if (OpenDialog1-> Execute ()) New ClientThread (addr, port, opendialog1-> filename); // begin to send data}} Server: .h File // My Comments: // At design-time, please place a TServerSocket Component on your form and set its clientype to stThreadBlocking.//Server Thread Class // The Server Can not only receives the packages coming from Clients, but also deliver the package to the clients afterprocessing upon the package.class SrvThread: public TServerClientThread {private: UINT FTimeOut; TWinSocketStream * WskStream; TThread * pThread; protected: void __fastcall ClientExecute (); public: __fastcall SrvThread (TServerClientWinSocket *); __property UINT TimeOut = {read = FTimeOut, write = FTimeOut};}; void __fastcall SrvThread :: ClientExecute () {TimeOut = 60000; file: // 60 Seconds WskStream = new TWinSocketStream (ClientSocket, TimeOut); file: // Send Text or File Char flagbuf [5]; char buf [4 096]; CHAR iPADDRESS [32]; SMS [0] = '/ 0'; RecipAddr [0] = '/ 0'; if (WSKStream-> WaitFordata (Timeout) File: // Obtain Flag: file or text { WSKSTREAM-> Read (Flagbuf, 5);} file: // save the flag received from Clom Clom Clom Clients Strcpy (Flag, Flagbuf); IF (StrPas (Flagbuf) == "TEXT") {

IF (WSKStream-> Waitfordata) {wskstream-> read (iPaddress, 32);} file: // save the client's ipaddress struct (Recipaddr, ipaddress);

IF (WSKStream-> Waitfordata) {wskstream-> read (buf, 4096);} file: // save the short message (SMS, BUF);

Savelog ("Received A TEXT!"); SAVELOG ("Client:" StrPas (iPaddress) "/ R / NStart Time:" DateTimetostr (now ())); SAVELOG ("Text Content:" StrPas (SMS )); SAVELOG ("Client:" StrPas (iPaddress) "/ R / Nend Time:" DateTimetostr (now ())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) (buf)); FLASHWINFO FSHINFO; :: ZeroMemory (& FSHINFO, sizeof (FLASHWINFO)); FSHINFO.cbSize = sizeof (FLASHWINFO); FSHINFO.hwnd = Application-> Handle; FSHINFO.dwFlags = FLASHW_TRAY | FLASHW_CAPTION; FSHINFO.uCount = 10; fshinfo.dwtimeout = 200; :: flashwindowex; if (form1-> adv-> checked) // Automatically Deliver to client {ix (flag) .Isempty () || strpas (recipaddr) .ISEMPTY () || StrPas (SMS) .Isempty ()) {Application-> MessageBox ("You Can't Deliver Because No Data Are Received!", "Error", MB_OK MB_ICONERROR); Return;} wskstream-> Write Flagbuf, 5); WSKSTREAM-> Write (Form1-> ComboBox1-> text.c_str (), 32); WS KStream-> Write (SMS, 4096); :: Sleep (500); // delay for 500ms clientsocket-> close ();} if (form1-> spt-> checked) // Automatical Deliver to Serial Port on local Computer {STRCAT (SMS, FLAGBUF); STRCAT (SMS, FORM1-> ComboBOBOX1-> text.c_str ()); // savelog ("Write Serial Port" > Port); // SAVELOG ("START Time:" DateTimetostr (now ())); // Savelog ("End Time:" DateTimetostr (now ())); pthread = new TWRITECMTHREAD (Form1-> Port, Form1->

BAUDRATE, (VOID *) BUF, 1000); pthread-> terminate ();}} else {

IF (StrPas (Flagbuf) .POS ("Get")) File: // GPRS {IF (WSKStream-> WaitFordata) {wskstream-> read (buf, 4096);} file: // save the flag to Flag STRCPY (FLAG, "GPRS"); File: // Save The Frame To SMS STRCPY (SMS, BUF); File: // Set The Destination IP STRCPY (Recipaddr, "127.0.0.1"); SAVELOG ("Received A Package from GPRS "); SAVELOG (" START TIME: " DateTimetostr (now ())); SAVELOG (SAF)); SAVELOG (" End Time: " DateTimetostr (now ()))) Form1-> Memo1-> Lines-> Add (StrPas (Flagbuf) StrPas (BUF)); Flashwinfo FshInfo; :: ZeromeMory (& FshInfo); fshinfo.cbsize = sizeof (Flashwinfo); fshinfo.hwnd = Application-> Handle; FSHINFO.dwFlags = FLASHW_TRAY | FLASHW_CAPTION; FSHINFO.uCount = 10; FSHINFO.dwTimeout = 200; :: FlashWindowEx (& FSHINFO); if (Form1-> adv-> Checked) {if (StrPas (Flag) .Ise .ise .ise .ise Mpty () || StrPas (RecipAddr) .Isempty () || StrPas (SMS) .Isempty ()) {Application-> MessageBox ("You Can't Deliver Because No Data Are Received!", "Error", MB_OK MB_ICONERROR); return; wskstream-> Write (flagbuf, 5); wskstream-> write (form1-> comboBoX1-> text.c_str (), 32); wskstream-> Write (SMS, 4096); :: SLEEP 500); // ms clientsocket-> close ();} if (form1-> spt-> checked) file: // Automatically Deliver to Serial Port On Local Computer {STRCAT (SMS, Flagbuf);

STRCAT (SMS, FORM1-> ComboBOBOX1-> text.c_str ()); File: // SaveLog ("Write Serial Port" > Port); File: // Savelog ("Start Time:" DateTimetostr (now ()); File: // savelog ("end time:" DateTimetostr (now ())); pthread = new twritecommthread (Form1-> Port, Form1-> Baudrate, (void *) SMS, 4096); pthread -> Terminate ();}} else {int Nlen; int nsize; int hfile; char path [255]; file: // path char filename [255]; file: // filename char fileExt [5]; file: / / Extension static int num = 0; file: // Obtain the directory's name if (WskStream-> WaitForData (TimeOut)) {WskStream-> Read (Path, 255);} file: // If the directory obtained from client doesnot exist , the create it if (! Directoryexists (STRPAS (PATH))) {createdir (strPas (path));} file: // Obtain the filename if (WSKSTream-> Waitford ATA (timeout) {wskstream-> read (filename, 255);} file: // Obtain the extension if (wskstream-> Waitfordata (timeout) {wskstream-> read (FileExt, 5);} file: // Obtain the client's IPAddress if (WskStream-> WaitForData (TimeOut)) {WskStream-> Read (IPAddress, 32);} file: // Save the client's IPAddress strcpy (RecIPAddr, IPAddress); AnsiString S = StrPas (Path) StrPas (FileEname) strpas (fileext); strcpy (buf, s.c_str ()); while (1) {if (FileExists (buf)) {s =

STRPAS (PATH) STRPAS (FileName) "FileExt); WSPrintf (buf, s.c_str (), NUM); Num ; file: // created susscessful} else break;} hfile = filecreate BUF); if (hfile == - 1) {Application-> MessageBox ("Failed to Create File ON Server!", "Error", MB_OK MB_ICONERROR); delete wskstream; terminate ();} File: // Save the FileName Received from Clom Clom Clom Clom Clom Clom Clom Clom Clom Clients Strncpy (Recfile, BUF, 255); SAVELOG ("Received A File:" STRPAS (BUF)); SAVELOG ("Client:" StrPas (ipaddress) "/ R / NStart Time:" DateTimetostr (now ())); try {

DWORD DWTICK = gettickcount (); file: // Obtain the lengthiff (wskstream-> Waitfordata) {nlen = wskstream-> read (& nsize, 4); if (Nlen! = 4) nsize = 0;} else nsize = 0; file: // = NLEN) {if (! WSKSTREAM-> WAITFORDATA (5000)) {IF (GettickCount () - dwtick Read (BUF, SIZEOF (BUF)); DWTICK = GetTickCount (); IF (Nlen <= 0) {file: // read error :: MessageBox (Null, "Read Error, The Thread Has Been Termin ATED! "," Error ", MB_ok | MB_ICONERROR); Break;} file: // Combine The Data FileWrite (HFILE, BUF, NLEN);} SAVELOG (" Client: " StrPas (ipaddress) " / R / NEND Time: " DateTimetostr (now ())); Form1-> Memo1-> Lines-> Add (" You Got A File Received from Client, Which Was Saved IN " StrPas (PATH)); File: // Application- > MessageBox ("Server Has SuccessFully Received The Data!", "Notification", MB_ok MB_ICONInformation; Flashwinfo fshinfo; :: ZeromeMory (& &)

FSHINFO, sizeof (FLASHWINFO)); FSHINFO.cbSize = sizeof (FLASHWINFO); FSHINFO.hwnd = Application-> Handle; FSHINFO.dwFlags = FLASHW_TRAY | FLASHW_CAPTION; FSHINFO.uCount = 10; FSHINFO.dwTimeout = 200; :: FlashWindowEx ( & Fshinfo); FileClose (HFile); // Read Completely

IF (form1-> adv-> checked) // Automatic or Deliver {IF (strPas (flag) .Isempty () || strpas (recipAddr) .ISEMPTY ()) {Application-> MessageBox ("You can't Deliver Because NO Data Are Received! "," Error ", MB_OK MB_ICONERROR); RETURN;} file: // send data try {buf [0] = '/ 0'; hfile = -1; hfile = fileopen (strPas (recfile), Fmopenread; if (hfile! = -1) {nsize = getFileSize ((Handle) Hfile, Null; File: // send the flag wskstream-> Write ("File / 0", 5); file: // send The name of directory wskstream-> write (Path, 255); file: // send the filename wskstream-> write (filename, 255); file: // send the extension of file wskstream-> write (fi Leext, 5); file: // send client's ip addresss wskstream-> write (form1-> comboBox1-> text.c_str (), 32); file: // send the length wskstream-> write (& nsize, 4); File: // send the data for (; nsize> 0; nsize- = Nlen) {nlen = min ((int) sizeof (buf), nsize); Nlen = FileRead (HFile, BUF, NLEN); IF (Nlen < = 0) Break; WSKSTREAM-> Write (buf, nlen);}}

} // try catch (Exception & E) {ClientSocket-> Close (); :: messagebox (0, E.MESSAGE.C_STR (), "Error", MB_OK | MB_ICONERROR);} fileclose (hfile);} // if

} // catch catch (Exception & E) {ClientSocket-> Close () ;:: MessageBox (0, E.MESSAGE.C_STR (), "Error", MB_ICONEROR);}

}} Delete wskstream; wskstream = null ;:: Sleep (100);

// at serversocket's ongetthread event to new a thread to communication with the requested client

Void __fastcall tform1 :: serversocket1getthread (Tobject * Sender, TSERVERCLIENTWINSOCKET * Clientsocket, TServerClientthRead * & socketthread) {

Socketthread = New SRVTHREAD (ClientSocket);

} The metioned-written codes is used to test a hardware.It can be run correctly.As many different applications, so you only reference it and could not be copy completely.It is important to know the principle of TServerSocket, TClientSocket and how VCL wraps the socket api.This article only provides the support of TCP protocol.The next article I will write will accomplish TCP and UDP protocol, please pay your attention for it.At this time, I would like to thank jishiping (JSP) and Raptor For their help.thanks for browsing it.i am can be contacted via e-mail: kingcaiyao@163.com

The above programs can realize the two-way communication between the server and the client, only one port, the working principle is similar to IE, and the client actively initiates the connection, the server side is processed after receiving the packet, and then according to established Link, write the data back to the client. At the same time on the two local area, it is tested on the local area, while the other is tested on the public network. Also I started to contact the network program from last year, and I got the guidance and help from JISHIPING, RAPTOR, and thank them again.

In addition, when I have a note to edit the code after copying, I found that all the comment portions added a file :, so when you see the file: prefix, that is, notes, not code, this statement

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

New Post(0)