How to point to the point to realize multi-line computers

zhaozj2021-02-16  45

In today's network applications, the transfer of files is one of the important features, and it is also the foundation of sharing. Some important protocols are like HTTP, FTP, etc. support file transfer. Especially FTP, its full name is "Document Transfer Agreement", the original engineer design this agreement is to solve the problem of file transfer between the network, and maintain a lot of vitality in its stable, high-speed, simple and simple. As a programmer, use these existing protocol delivery files is quite simple, however, they are only available in server mode. This way, when we want to transfer files between point and point, it does not apply or quite troubles, there is a small use of a big knife. The author always wants to seek a simple and effective way to renew the sequel of the multi-line computers to achieve the file transfer problem between point and point. After a lot of flipping information and test, it is finally realized, and it is now shared, and Everyone is shared. (I wrote a utility based on this (network church, including source code), can be used on IP / TCP-based computers for everyone to learn. Download address: http://h2osky.126.com) Implementation Method (VC , TCP / IP protocol) is as follows: Still use of servers and customer mode, need to be designed and programmed separately. The server is simpler, mainly to join the code, listen to customers, and transfer files. And those breakpoint resumes, and the management of documents is placed on the client. First, internet server: The first thing we have to define a simple protocol, which is the language that defines a server-side to understand. In order to simplify the problem, I will let the server understand two sentences, one is that the customer says "I want to read the information", and I am "I am ready, you can pass the file." Because of the multi-thread, the function must be independent, and the package is threaded, first build a listening thread, mainly responsible for accessing the customer, and launch another customer thread. I use VC as follows:

DWORD WINAPI LISTENTHREAD (LPVOID LPPARAM) {

File: // Sockets Socket PTHIS = (Socket) LPPARAM; File: // Start listening Int rc = listen (PTHIS, 30); file: // Display information IF (RC < 0) {CSTRING AAA; AAA = "Listen Error / N"; AFXGETMAINWND () -> SendMessageTodescendants (WM_AGE1, (LPARAM) AAA.GetBuffer (0), 1); AAA.RELEASEBUFFER (); return 0;} file: / / Enter the cycle, and receive the socket while (1) {file: // Newly built a socket for the client http://h2osky.126.com socket S1; S1 = Accept (PTHIS, NULL, NULL); file: // give the main function to join the message cstring aa; AA = "One person is incorporated! / N"; AFXGETMAINWND () -> SendMessageTodescendants (WM_AGE1, (LPARAM) aa.getBuffer (0), 1) Aa.releaseBuffer (); DWORD DWTHREAD; File: // Create User Thread :: CreateThread (Null, 0, Clientthread, (LPVOID) S1, 0, & DWTHREAD;} Return 0;

} Next, let's look at the user thread: first look at the file message class definition: struct fileinfo {int fileno; // file number int type; // Client thinking what (the first two words, use 1, 2) Long Len ; // File length int seek; // file start position, used for multi-thread char name [100]; // file name http://h2osky.126.com}; file: // User thread function: DWord WinAPI ClientthRead (LPVOID LPPARAM) {file: // File message fileInfo * fiinfo; file: // Receive Cache Char * m_buf; m_buf = new char [100]; file: // Listening to user socket socket pthis = Socket) LPPARAM; File: // Read the information INT AA = Readn (PTHIS, M_BUF, 100); file: // Returns IF (AA ​​<0) {CloseSocket (PTHIS) if there is any error; return -1; } File: // Transfer the file information of the transmitted information into defined file information fiInfo = (fileInfo *) m_buf;

CSTRING AAA; File: // Test customer wants to say what switch (fiInfo-> type) {file: // I want to read file information case 0: file: // read file aa = sendn (pthis, (char *) zmfile, 1080); File: // Wrong IF (AA ​​<0) {CloseSocket (PTHIS); Return -1;} file: // Send message to the main function AAA = "Receive list command / N"; AFXGETMAINWND () - > SendMessageTodescendants (WM_AGE1, (LPARAM) AAA.GetBuffer (0), 1); Break; File: // I am ready, you can pass files

Case 2: file: // Send a file message to the main function AAA.Format ("% s file is requested!% s / n", zmfile [fiinfo-> fileno] .name, nameph [fiInfo-> fileno]); afxgetmainwnd () -> SendMessageTodescendants (WM_AGE1, (LPARAM) AAA.GetBuffer (0), 1); File: // Read file, and transmit readfile (pthis, fiinfo-> seek, fiinfo-> len, fiInfo-> fileno); File: // Do not understand what you said: aaa = "Receive protocol error! / n"; AFXGETMAINWND () -> SendMessageTodescendants (WM_AGE1, (LPARAM) AAA.GetBuffer (0), 1); Break;}

Return 0;}

/Http://h2osky.126.comfile: // Read file function void readfile (socket so, int seek, int LEN, int fixo) {file: // file name cstring myname;

MyName.Format ("% s", nameph [fino]);

Cfile myfile; file: // Open file myfile.open (MyName, cfile :: moderad | cfile :: typebinary | cfile :: sharedenynone); file: // Transfer to the specified location MyFile.seek (seek, cfile :: begin) CHAR M_BUF [SIZE]; INT LEN2; INT LEN1; LEN1 = LEN; File: // Start receiving until the entire file while (len1> 0) {len2 = len> size? Size: len; myfile.read M_buf, len2); int aa = sendn (SO, M_BUF, LEN2); IF (AA ​​<0) {CloseSocket (SO); Break;} len1 = len1-aa; len = len-aa;} myfile.close () } The most important function of the server side is these, the client is introduced: the client is most important, the most complex, it is responsible for the management, progress record of threads, etc. The approximate process is as follows: first connect the server, then send command 1 (give me file information), including file length, name, etc., then divide several threads download according to length, and make a download process, then send command 2 (can Give me a file) and record the file process. Finally, the end. One of this is a very important class, that is, the cdownload class, is defined as follows: Class CDownload {public:

void createthread (); // Open Circuit http://h2osky.126.com DWord finish1 (); // Complete thread int sendlist (); // send command 1 DOWNFO DOINFO; // File information (like server definition) INT Startask (INT N); Bool Good [Black]; Int FileRange [100]; CSTRING FNAME; CSTRING FNAMETWO; uint threadfunc (long index); // Download process

Int SendRequest (int N); // Send File Information CDownload (INT THNO1); Virtual ~ cdownload ();

}

Let's first introduce SendRequest (int N). Before starting, send the file message command to the server so that the client knows what files can pass cd cdownload :: SendRequest (int N) {file: // Building socket SockAddr_in Local; Socket M_Socket;

INT RC = 0; file: // Entry server address local.sin_family = AF_INET; local.sin_port = HTONS (1028); local.sin_addr.s_un.s_addr = inet_addr (ip); m_socket = socket (AF_INET, SOCK_STREAM, 0);

int RET; File: / / Database RET = Connect (m_socket, (lpsockAddr) & local, sizeof (local)); file: // is wrong if (RET <0) {AFXMessageBox ("Database & S)); CloseSocket m_socket); return -1;} file: // Initialization command fileinfo fileinfo1; fileinfo1.len = n; fileinfo1.seek = 50; fileinfo1.type = 1; file: // Send command int aa = sendn (m_socket, (char *) & fileInfo1,100); if (aa <0) {CloseSocket (m_socket); return -1;} file: // receive information from the server AA = readn (m_socket, (char *) & fileInfo1,100) ; If (aa <0) {CloseSocket (m_socket); return -1;} file: // Turn shutdown (m_socket, 2); CloseSocket (m_socket); Return 1;}

With the file news, we can download the file in the main function, the usage is as follows: file: // Download the cloken file and build a new cdownload class Down [ClNo] = New CDownload (Clno); File: // Start downloading, and make TYPE = DOWN [Clno] -> Startask (ClN); File: // Establish each thread CreethRead (CLNO);

Introduction Start Method File: // Start Method INT CDownload :: Startask (INT N) {

File: // Read file length DOINFO.FILEN = zmfile [n] .length; file: // Read Name FNAME = zmfile [n] .name; cstract tmep; file: // Etenna file name TMEP.FORMAT ("// Temp //% S", FNAME);

File: // Give the main function sent message cstring aaa; AAA = "is reading" FNAME "information, start downloading ... / n" immediately; AFXGETMAINWND () -> SendMessageTodescendants (WM_AGE1, (LPARAM) AAA.GetBuffer 0), 1); AAA.RELEASEBUFFER (); file: // Returns if the file length is less than 0, return if (DOINFO.FILEN <= 0) Return -1; file: // Built a file record file ended with .down Information cstring m_temp; m_temp = fname ". Dwon"; doinfo.name = m_temp; file * fp = null; cfile myfile; file: // If it is the first download file, the initialization of each record file

IF ((fp = fopen (m_temp, "r")) == null) {

FileRANGe [0] = 0; file: // File block for (int i = 0; i 0) fileERANGE [i * 2] = i * (DOINFO.FILEN / BLACK 1); fileERANGE [i * 2 1] = doinfo.filelen / Black 1;} filerenge [black * 2-1] = doinfo.filelen-filerange [Black * 2-2];

MyFile.Open (m_temp, cfile :: modecreate | cfile :: modewrite | cfile :: typebinary); file: // Write file length myfile.write (& DOINFO.FILEN, SIZEOF (int)); MyFile.Close (); CSTRING TEMP; For (INT II = 0; II

Temp.format (". DOWN% D", II); m_temp = fname temp; myfile.open (m_temp, cfile :: modecreate | cfile :: modewrite | cfile :: typebinary); file: // Write processes File Information MyFile.Write (& FileRANGe [II * 2], SIZEOF (INT)); MyFile.Write (& FileRange [II * 2 1], SIZEOF (Int)); myfile.close ();}

((Cmainframe *) :: afxgetmainwnd ()) -> m_work.m_listctrl-> additemtwo (n, 2,0,0,0, doinfo.threadno);

} file: // If the file already exists, the description is the renewal, read the last information else {file: // Open Fread (& Doinfo.filelen, SizeOf (int), 1, fp);

Fclose (fp);

CSTRING TEMP; M_TEMP = FNAME ". DOWN0"; IF ((fp = fopen (m_temp, "r")) == null) Return 1; Else Fclose (FP); int bb; bb = 0; file: // Read Information for each process log (INT II = 0; II

BB = BB FileRANGE [II * 2 1]; CSTRING TEMP;

} IF (bb == 0) Return 1; doinfo.totle = DOINFO.FILEN-BB;

(CMAINFRAME *) :: AFXGETMAINWND () -> m_work.m_listctrl-> additemtwo (n, 2, doinfo.totle, 1, 0, doinfo.threadno);

}

File: // Establish the download end process Timethread to rely on each process end time. DWORD DWTHREAD; :: CreateThread (Null, 0, Timethread, (LPVOID) this, 0, & dwthread;

RETURN 0;} file: // The following describes the establishment of the process functions, very simple: http://h2osky.126.comvoid cmainframe :: CreateThread (int threadno) {dword dwthread; file: // Establish your BLACK process for (int i = 0; i

DWORD WINAPI downthread (LPVOID lpparam) {cdownload * pthis = (cdownload *) lpparam; file: // Process primer cord 1 InterlockedIncrement (& pthis-> m_index); file: // execute the download process pthis-> threadfunc (pthis-> m_index -1); return 1;} The following describes the download process function, the most core thing UINT cdownload :: threadfunc (long index) {file: // Initialization Joint SockAddr_in local; socket m_socket;

INT RC = 0; local.sin_family = af_INET; local.sin_port = HTONS (1028); local.sin_addr.s_un.s_addr = inet_addr (ip); m_socket = socket (AF_INET, SOCK_STREAM, 0);

INT RET; File: // Read Cache Char * m_buf = New Char [Size]; Int Re, Len2; FileInfo Fileinfo1; File: // Connect Ret = Connect (m_socket, (lpsockAddr) & local, sizeof (local)); File: // Read the download information for each process Fileinfo1.len = filerange [index * 2 1]; fileinfo1.seek = filerenge [index * 2]; fileinfo1.type = 2; fileinfo1.fileno = DOINFO.THREADNO; RE = fileInfo1.1;

File: // Open the file cfile destfile; file * fp = null; file: // is the first time IF ((fp = fopen (FP = FOPEN (R ") == NULL)

Destfile.open (FName, CFile :: Modecreate | CFILE :: Modewrite | CFILE :: Typebinary | CFILE :: Sharednynone;

Else

File: // If the file exists, it is a renewal Destfile.Open (FNAME, CFile :: Modewrite | cfile :: typebinary | cfile :: sharednynne); file: // File Pointer Move to Specify location destfile.seek (Filerange [Index * 2], cfile :: begin; file: // Send a message to the server, you can pass the file sendn (m_socket, (char *) & fileInfo1, 100);

CFILE MYFILE; File: // Initialization Process Information Http://h2osky.126.com cstring Temp; Temp.format (". DOWN% D", INDEX); m_temp = fname TEMP;

File: // When the length is not 0 when the length is not 0 while (re> 0) {len2 = RE> Size? size: re; file: // reads the content int LEN1 = readn (m_socket, m_buf, len2); File: // If you have a wrong, if (len1 <0) {CloseSocket (M_Socket); Break;} file: // Write Document Destfile.Write (m_buf, len1);

FILE: / / Change the recording schedule information

FileRANGE [Index * 2 1] - = len1; fileERANGE [INDEX * 2] = len1; file: // Move record file pointer to Myfile.seek; file: // Write record Progress MyFile.Write (& FileRANGE [INDEX * 2], SIZEOF (INT)); MyFile.Write (& FileRange [INDEX * 2 1], SIZEOF (int));

File: // minus the length of this reading

RE = RE-LEN1;

File: // Document length DOINFO.TOTLE = DOINFO.TOTLE LEN1;

}; File: // This piece is complete, ending myfile.close (); delete.close (); delete [] m_buf; shutdown (m_socket, 2); if (RE <= 0) Good [index] = true; Return 1;} The main modules and mechanisms of this client have been basically introduced. I hope to take a good way to renew this multi-line comparison. I wrote a very basic utility (network church, including source code), available on IP / TCP-based computers for you to learn. Download address: http://h2osky.126.com Zhao Ming Email: papaya_zm@sina.com; zmpapaya@hotmail.comweb: http://h2osky.126.com

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

New Post(0)