Implementation of a socket-based Resource Sharing Platform (I)

Source: Internet
Author: User

Some time ago, I worked with my friends on a rough model similar to the plug-in, thunder + MSN tool. Basically, all functions were implemented from the socket communication level.

The overall architecture is the C/S architecture, which is implemented using MFC. Technically, it is very old. This article mainly introduces the design idea and part of the code framework of a software similar to the plug-in.

The code we implement is not very optimized. It is only evidence of the design philosophy.

 

My initial idea for this small software was to facilitate resource sharing and communication between large and medium-sized enterprises in a small network.

Everyone can share part of their own files. Of course, this can be implemented through Windows Shared Folders or Linux samba, but if I do not know how to share the source, it is difficult to obtain resources. Some people say that the resources shared by everyone on the LAN can be seen directly in the Windows Network neighbors, but I found that due to the relationship between various network settings, I often cannot see the resources shared by others in my network neighbors.

 

So at that time, I used several windows APIs (I forgot what it was, and I could detect and traverse directories shared by others). The writing results were not good, and the first was very slow, the second is incomplete, and the third is uncontrollable. The encapsulation is too high to hide n technical details.

 

Then I thought, I started from the underlying layer based on socket.

Without knowing the source, how can we detect and collect shared resources from various sources? -- The answer soon came to the fore, getting a server. everyone connected to the server and told it about its own resources. Then, everyone would query shared resources on the network from the server, create a point-to-point connection on the client to transfer files.

 

 

 

The overall architecture of the program is very simple. The purpose of this article is to tell you some key points in this software implementation step by step.

 

1. Internal protocols

 

Our client needs to "communicate" with the server, so we have to have a set of languages within the system that can be recognized by each other. Such a set of protocols can be completely designed by ourselves.

I used UDP Communication in implementation. The first byte of each UDP packet is the Instruction byte, followed by the format and parameters of each instruction. For example, some of my "internal protocol" code:

 

/*************************************** * *****/<Br/> // C-> S user heartbeat <br/> # define ns_udp_living0x03 </P> <p>/C-> S user update shared information <br/> # define ns_udp_update0x04 </P> <p>/C-> S user search <br/> # define ns_udp_search0x05 </P> <p>/ /C-> S to obtain the online user list <br/> # define ns_udp_get_online_users0x06 </P> <p>/C-> S to apply for broadcast messages <br/> # define ns_udp_client_boradcast0x07 </P> <p>/C-> S apply to download the new client version <br/> # define ns_udp_client_getexe0x08 </P> <p> /********* **********************************/</P> <p> // s-> C User Logon successful <br/> # define ns_udp_login_success0x71 </P> <p> // s-> C transfer search results <br/> # define ns_udp_pushinfo0x72 </P> <p> // s-> C transfer online user list <br/> # define ns_udp_push_online_users0x73 </P> <p>/S-> C broadcast message <br/> # define ns_udp_broadcast_message0x74 </P> <p> // s-> restart the C server, kick out all users <br/> # define ns_udp_server_restart0x75 </P> <p>/S-> C. Collect shared data again <br/> # define ns_udp_recollect_1_files0x76 </P> <p>> // s-> C kill user <br/> # define ns_udp_kick0x77 </P> <p>/S-> C client update package <br/> # define ns_udp_client_update0x78 </P> <p> /********************************* * ***********/</P> <p>/C-> C file acquisition <br/> # define ns_udp_getfile0x80 </P> <p> // C-> C file license <br/> # define ns_udp_allow_getfile0x81 </P> <p>/C-> C chat message <br/> # define ns_udp_message0x82

 

If the plain text is sent directly on the network, it is easy to be captured by someone else using the packet capture tool. The content can be understood through a slight analysis, then, someone else can simulate writing a client or program to illegally access and attack your server and other clients. Therefore, encryption algorithms should be used to transmit encrypted data over the network. This is not implemented in my "rough" program, but any commercial communication program released on the internet is necessary.

 

2. TCP file transmission and transmission group management.

 

When one party applies for download, the other party should respond to the request and establish a TCP connection for it. The former is called the tcp client and the latter is the TCP server. Based on our "sharing" idea, every client program may be used as a tcp client (download resources) or a TCP server (provide resource download ), the server can also act as a TCP server (publish an automatic client upgrade package ).

 

To sum up the core idea, both the client and the server should have a TCP listener that constantly listens to TCP requests on the network and establishes a connection with each request, in addition, a separate thread is added for file transmission through communication. This mechanism is called TCP File Transfer group management.

 

Transmission group management should include the following points:

1. Listen for requests and establish a connection;

2. added a thread for the connection;

3. Control Transmission Service;

4. Stop Transmission and close the thread.

 

The following code is the core part of the transmission group management:

 

Generally, tcpservermanager is the transmission group management. Each connection starts a tcptaskmanager as the container class for TCP transmission and is responsible for managing a TCP transmission task.

 

 

# Ifndef netshare_tcp_server_manager_h _ <br/> # define netshare_tcp_server_manager_h _ </P> <p> # include "tcpserver. H "<br/> # include" netshareudp. H "<br/> # include <cpplib/mutexlock. h> <br/> # include <string> <br/> # include <vector> <br/> # include <algorithm> </P> <p> using namespace STD; </P> <p> class tcptaskmanager; <br/> class tcpservermanager; </P> <p> // typedef void (tcpservermanager: * callback_delete) (INT ); </P> <P> // data structure of the sending file <br/> struct sendfilestructtype <br/>{< br/> string filename; <br/> string IP; <br/> string dir; <br/> DWORD offset; </P> <p> tcptaskmanager * p_manager; <br/> }; </P> <p> // TCP subtask manager <br/> class tcptaskmanager <br/> {<br/> Public: <br/> tcptaskmanager (sendfilestructtype task) <br/>: m_speed (0) <br/>, m_task (task) <br/>, m_maxspeed (0) <br/>, m_isfinish (false) <br/>, m_taskhandler (0) <br/> {<Br/> // This-> Run (); <br/> m_ptcpserverinstance = new tcp_server (); <br/>}</P> <p> ~ Tcptaskmanager () {}</P> <p> /////////////////////////////// //////////////////////////////////////// /// <br/> void speed (DWORD speed) {m_speed = speed ;}< br/> DWORD speed () {return m_speed ;}</P> <p> void setmaxspeed (DWORD speed) <br/>{< br/> m_maxspeed = speed; <br/> m_ptcpserverinstance-> setmaxspeed (speed ); <br/>}</P> <p> // call after sending is complete <br/> // The method is called and the corresponding objects of this class are not recycled and exist in m_ptasks of tcpservermanager. instance, <br/> // you must specify In pservermanager, determine the m_isfinish status bit and remove it. <Br/> void finish () <br/>{< br/> closehandle (m_taskhandler); <br/> m_isfinish = true; <br/>}</P> <p> bool checkfinish () {return m_isfinish;} <br/> tcp_server * gettcpserverinstanceptr () {return m_ptcpserverinstance ;} </P> <p> ///////////////////////////////// //////////////////////////////////////// /</P> <p> // TCP data transmission thread <br/> static DWORD winapi tcpsendthreadproc (lpvoid lpparameter) <br/>{< br/> sendfilestru Cttype * ptype = (sendfilestructtype *) (lpparameter); <br/> string IP = ptype-> IP; <br/> string filename = ptype-> filename; </P> <p> // tcp_server serverinstance; <br/> tcp_server * pserverinstance = ptype-> p_manager-> gettcpserverinstanceptr (); <br/> pserverinstance-> setdir (ptype-> DIR); <br/> pserverinstance-> bindmanager (ptype-> p_manager ); <br/> pserverinstance-> sendfile (IP, tcp_trancesport_port, filename, Ptype-> offset); </P> <p> ptype-> p_manager-> finish (); <br/> return 0; <br/>}</P> <p> void run () <br/>{< br/> m_task.p_manager = This; <br/> m_taskhandler = createthread (null, 0, tcpsendthreadproc, (lpvoid) & m_task, 0, null); <br/>}</P> <p> protected: <br/> DWORD m_speed; // current speed <br/> DWORD m_maxspeed; // maximum transmission speed <br/> sendfilestructtype m_task; <br/> handle m_taskhandler; <br/> bool m_isfinish; <br/> tcp_server * m _ Ptcpserverinstance; <br/> }; </P> <p> namespace <br/> {<br/> // check whether a task has been completed <br/> bool completedtask (tcptaskmanager * task) <br/>{< br/> return (Task-> checkfinish ()); <br/>}</P> <p> // management class tcpservermanager <br/> {<br/> public: <br/> tcpservermanager () {}< br/> ~ Tcpservermanager () {}</P> <p> // Add a file transfer task <br/> bool addtask (sendfilestructtype task ); </P> <p> // set the overall maximum sending speed <br/> void maxspeed (DWORD speed) <br/>{< br/> m_maxspeed = speed; <br/> adjustspeed (); <br/>}</P> <p> // delete a download task numbered with ID <br/> void Delete (size_t ID) <br/>{< br/> taskmutex. lock (); <br/> vector <tcptaskmanager *>: iterator iter = m_ptasks.begin (); <br/> for (size_t I = 0; I <ID; I ++) <br/> ++ ITER; <br/> DELE Te * ITER; <br/> m_ptasks.erase (ITER); <br/> taskmutex. unlock (); </P> <p> adjustspeed (); <br/>}</P> <p> // remove all completed tasks <br/> void clearcompletetask () <br/>{< br/> try <br/>{< br/> taskmutex. lock (); <br/> vector <tcptaskmanager *>: iterator new_end = remove_if (m_ptasks.begin (), m_ptasks.end (), completedtask ); <br/> for (vector <tcptaskmanager *>: iterator iter = new_end; iter! = M_ptasks.end (); ++ ITER) <br/> Delete * ITER; <br/> m_ptasks.erase (new_end, m_ptasks.end ()); </P> <p> int K = m_ptasks.size (); <br/> taskmutex. unlock (); <br/>}< br/> catch (...) <br/>{</P> <p >}< br/>}</P> <p> protected: </P> <p> // obtain the overall sending speed <br/> DWORD getcurrtotalspeed () <br/>{< br/> taskmutex. lock (); <br/> DWORD sum = 0; <br/> for (vector <tcptaskmanager *>: iterator iter = m_ptasks.begin (); <br/> iter! = M_ptasks.end (); <br/> ++ ITER) <br/>{< br/> sum + = (* ITER)-> speed (); <br/>}< br/> taskmutex. unlock (); <br/> return sum; <br/>}</P> <p> // get the number of current transfer tasks <br/> int gettasknum () <br/>{< br/> clearcompletetask (); <br/> return m_ptasks.size (); <br/>}</P> <p> // adjust the sending speed of all sending tasks. <br/> // temporarily evenly distributed <br/> void adjustspeed () <br/> {<br/> If (m_maxspeed = 0 | gettasknum () = 0) <br/> return; </P> <p> DWORD singlemaxspeed = m_maxspe Ed/gettasknum (); <br/> taskmutex. lock (); <br/> for (vector <tcptaskmanager *>: iterator iter = m_ptasks.begin (); <br/> iter! = M_ptasks.end (); <br/> ++ ITER) <br/>{< br/> (* ITER)-> setmaxspeed (singlemaxspeed ); <br/>}< br/> taskmutex. unlock (); <br/>}</P> <p> PRIVATE: <br/> DWORD m_maxspeed; // overall maximum sending speed <br/> vector <tcptaskmanager *> m_ptasks; <br/> cpplib: Resource: mutex taskmutex; // access the mutex lock of m_task <br/>}; </P> <p> # endif

 

 

Not yet to be continued ....

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.