Encapsulation of P2P Holes

Source: Internet
Author: User
Tags socket error htons

Encapsulate them and are studying this thing.

 

# Ifndef _ mysocket_h _ <br/> # DEFINE _ mysocket_h _ </P> <p> # include <winsock2.h> <br/> # include "exception. H "</P> <p> class cmysocket <br/>{< br/> Public: <br/> cmysocket (INT type ); </P> <p> void BIND (); <br/> inline int sendto (char far * Buf, int Len, int flags, struct sockaddr far *, int far * tolen); <br/> inline int sendto (char far * Buf, int Len, int flags, const IPaddress & IPaddress ); </P> <p> inline int recvfro M (char far * Buf, int Len, int flags, struct sockaddr far * From, int far * fromlen); <br/> inline int recvfrom (char far * Buf, int Len, int flags, const IPaddress & IPaddress); </P> <p> protected: <br/> socket m_socket; <br/> }; </P> <p> class IPaddress <br/> {<br/> Public: <br/> IPaddress () <br/>{< br/> memset (& Address, 0, sizeof address); <br/> address. sin_family = af_inet; <br/> address. sin_addr.s_un.s_addr = HT Onl (inaddr_any); <br/>}</P> <p> IPaddress (const char * IP, DWORD port) <br/>{< br/> assert (IP! = NULL); <br/> address. sin_family = af_inet; <br/> address. sin_addr.s_un.s_addr = inet_addr (serverip); <br/> address. sin_port = htons (port); <br/>}</P> <p> void setip (const char * IP) <br/>{< br/> address. sin_addr.s_un.s_addr = inet_addr (IP); <br/>}</P> <p> void setport (DWORD port) <br/>{< br/> address. sin_port = htons (port); <br/>}</P> <p> void setaddress (const char * IP, DWORD port) <br/>{< br/> assert (IP! = NULL); <br/> address. sin_addr.s_un.s_addr = inet_addr (IP); <br/> address. sin_port = htons (port); <br/>}</P> <p> const socketaddr_in * operator & () <br/>{< br/> return & address; <br/>}</P> <p> // const socketaddr </P> <p> socketaddr_in & getrawelem () {return address ;} </P> <p> PRIVATE: <br/> socketaddr_in address; <br/> }; </P> <p> # endif </P> <p> # include "stdafx. H "</P> <p> # include" mysocket. H "<br/> # include <winsock2.h> <Br/> # pragma comment (Lib, "ws2_32.lib") </P> <p> cmysocket: cmysocket (INT type) <br/>{< br/> wsadata; </P> <p> If (wsastartup (makeword (2, 2), & wsadata )! = 0) <br/>{< br/> printf ("Windows Sockets 2.2 startup"); <br/> throw exception (""); <br/>}< br/> else <br/> {<br/> printf ("using % s (Status: % s)/n ", <br/> wsadata. szdescription, wsadata. szsystemstatus); <br/> printf ("with API versions % d. % d to % d. % d/n ", <br/> lobyte (wsadata. wversion), hibyte (wsadata. wversion), <br/> lobyte (wsadata. whighversion), hibyte (wsadata. whighversion); <br/>}</P> <p> m_socket = sock Et (af_inet, type, 0); <br/> If (m_socket <0) <br/> {<br/> printf ("create socket error "); <br/> throw exception (""); <br/>}</P> <p> void cmysocket: BIND () <br/>{< br/> sockaddr_in sin; <br/> sin. sin_addr.s_un.s_addr = inaddr_any; <br/> sin. sin_family = af_inet; <br/> sin. sin_port = 0; </P> <p> If (BIND (m_socket, (struct sockaddr *) & sin, sizeof (SIN) <0) <br/> throw exception ("BIND error"); <br/>}</P> <p> Int cmysocket: sendto (char far * Buf, int Len, int flags, struct sockaddr far * To, int far * tolen) <br/>{< br/> assert (BUF! = NULL) & (! = NULL); </P> <p> return sendto (m_socket, Buf, Len, flags, to, tolen ); <br/>}</P> <p> int cmysocket: sendto (char far * Buf, int Len, int flags, const IPaddress & IPaddress) <br/>{< br/> return sendto (m_socket, Buf, Len, flags, & IPaddress, sizeof (sockaddr_in )); <br/>}</P> <p> int cmysocket: recvfrom (char far * Buf, int Len, int flags, struct sockaddr far * From, int far * fromlen) <br/>{< br/> assert (BUF! = NULL) & (from! = NULL); </P> <p> return recvfrom (m_socket, Buf, Len, flags, from, fromlen ); <br/>}</P> <p> int cmysocket: recvfrom (char far * Buf, int Len, int flags, const IPaddress & IPaddress) <br/>{< br/> return recvfrom (m_socket, Buf, Len, flags, & IPaddress, sizeof (sockaddr_in )); <br/>}</P> <p> # include "stdafx. H "<br/> # include" message. H "<br/> # include" mysocket. H "<br/> # include" serversocket. H "<br/> # include <Casse RT> </P> <p> # define server_port 2280 </P> <p> class cserversocket; <br/> class clientsocket: public cmysocket <br/>{< br/> Public: <br/> stuserlistnode * getuser (const char * username); <br/> void connecttoserver (const char * username, const char * serverip); <br/> bool sendmessageto (const char * username, const char * message); </P> <p> PRIVATE: <br/> userlist m_userlist; <br/> cserversocket * m_serversocket; <br/> }; </P> <p> stuserlistnode * clientsocket: getuser (const char * username) <br/>{< br/> for (userlist: iterator useriterator = m_userlist.begin (); <br/> useriterator! = M_userlist.end (); ++ useriterator) <br/>{< br/> If (strcmp (* useriterator)-> username), username) = 0) <br/> return * useriterator; <br/>}</P> <p> throw exception ("not find this user "); <br/>}</P> <p> void clientsocket: connecttoserver (const char * username, const char * serverip) <br/>{< br/> IPaddress serveraddr (serverip, server_port); </P> <p> stmessage sendbuf; <br/> sendbuf. msgtype = login_msg; <br/> Str Ncpy (sendbuf. msgbody. loginmember. username, username, 10); </P> <p> sendto (const char *) & sendbuf, sizeof (sendbuf), 0, (const sockaddr *) & serveraddr, sizeof (serveraddr); </P> <p> int usercount; <br/> int fromlen = sizeof (serveraddr ); <br/> int Iread = recvfrom (char *) & usercount, sizeof (INT), 0, (sockaddr *) & serveraddr, & fromlen ); <br/> If (Iread <= 0) <br/> {<br/> throw exception ("Login error/N "); <br/>}</P> <P> // After logging on to the server, receive the information of logged-on users sent from the server <br/> cout <"have" <usercount <"users logined Server: "<Endl; <br/> for (INT I = 0; I <usercount; I ++) <br/>{< br/> stuserlistnode * node = new stuserlistnode; <br/> recvfrom (char *) node, sizeof (stuserlistnode), 0, (sockaddr *) & serveraddr, & fromlen); <br/> m_userlist.push_back (node ); <br/> cout <"username:" <node-> username <Endl; <br/> in_addr TMP; <br/> TMP. s_un.s_addr = Htonl (node-> ip); <br/> cout <"userip:" <inet_ntoa (TMP) <Endl; <br/> cout <"userport: "<node-> port <Endl; <br/> cout <" "<Endl; <br/>}</P> <p>/* process user login */<br/> void proclogin () <br/>{< br/>; <br/>}</P> <p> bool clientsocket: sendmessageto (const char * username, const char * message) <br/>{< br/> char realmessage [256]; <br/> unsigned int userip; <br/> unsigned short userpor T; <br/> bool finduser = false; <br/> for (userlist: iterator useriterator = m_userlist.begin (); <br/> useriterator! = M_userlist.end (); ++ useriterator) <br/>{< br/> If (strcmp (* useriterator)-> username), username) = 0) <br/> {<br/> userip = (* useriterator)-> IP; <br/> userport = (* useriterator)-> port; <br/> finduser = true; <br/> break; <br/>}</P> <p> If (! Finduser) <br/> return false; </P> <p> strcpy (realmessage, message); <br/> for (INT I = 0; I <maxretry; I ++) <br/>{< br/> recvedack = false; <br/> IPaddress serveraddr (userip, userport); </P> <p> stp2pmessage messagehead; <br/> messagehead. imessagetype = p2pmessage; <br/> messagehead. istringlen = (INT) strlen (realmessage) + 1; <br/> int isend = sendto (m_serversocket, (const char *) & messagehead, sizeof (messagehead), 0, (const sockaddr *) & serveraddr, sizeof (serveraddr); <br/> isend = sendto (m_serversocket, (const char *) & realmessage, messagehead. istringlen, 0, (const sockaddr *) & serveraddr, sizeof (serveraddr )); </P> <p> // wait for the receiving thread to modify the mark <br/> for (Int J = 0; j <10; j ++) <br/>{< br/> If (recvedack) <br/> return true; <br/> else <br/> sleep (300 ); <br/>}</P> <p> // no response is received from the target host. The port ing of the target host is not found. <br/> // open, send the request information to the server and the server must notify the Target Master. Host <br/> // open the ing port (UDP) <br/> sockaddr_in server; <br/> server. sin_addr.s_un.s_addr = inet_addr (serverip); <br/> server. sin_family = af_inet; <br/> server. sin_port = htons (server_port); </P> <p> stmessage transmessage; <br/> transmessage. imessagetype = p2ptrans; <br/> strcpy (transmessage. message. translatemessage. username, username); </P> <p> sendto (m_serversocket, (const char *) & transmessage, sizeof (transmessage Ge), 0, (const sockaddr *) & server, sizeof (server); <br/> sleep (100); // wait for the recipient to send the message first. <Br/>}</P> <p> return false; <br/>}</P> <p> // message receiving thread <br/> DWORD winapi recvthreadproc (lpvoid lpparameter) <br/>{< br/> sockaddr_in serveraddr; <br/> int sinlen = sizeof (serveraddr); <br/> stp2pmessage recvbuf; <br/> cserversocket * pserversocket = (cserversocket *) lpparameter; <br/> for (;) <br/> {<br/> int Iread = recvfrom (* serversocket, (char *) & recvbuf, sizeof (recvbuf), 0, (sockaddr *) & serveraddr, & sinle N); <br/> If (Iread <= 0) <br/> {<br/> printf ("Recv error/N"); <br/> continue; <br/>}< br/> switch (recvbuf. imessagetype) <br/>{< br/> case p2pmessage: <br/>{< br/> // receives a P2P message <br/> char * comemessage = new char [recvbuf. istringlen]; <br/> int iread1 = recvfrom (* pserversocket, comemessage, 256, 0, (sockaddr *) & serveraddr, & sinlen ); <br/> comemessage [iread1-1] = '/0'; <br/> If (iread1 <= 0) <br/> throw exception ("R ECV message error/N "); <br/> else <br/> {<br/> printf (" Recv a message: % s/n ", comemessage ); </P> <p> stp2pmessage sendbuf; <br/> sendbuf. imessagetype = p2pmessageack; <br/> sendto (* pserversocket, (const char *) & sendbuf, sizeof (sendbuf), 0, (const sockaddr *) & serveraddr, sizeof (serveraddr); <br/>}< br/> Delete [] comemessage; <br/> break; <br/>}< br/> case p2psomeonewanttocallyou: <br/>{< br/> // receives the logging command to the specified IP Address Holes <br/> printf ("Recv p2someonewanttocallyou data/N"); <br/> sockaddr_in serveraddr; <br/> serveraddr. sin_addr.s_un.s_addr = htonl (recvbuf. istringlen); <br/> serveraddr. sin_family = af_inet; <br/> serveraddr. sin_port = htons (recvbuf. port); </P> <p> // UDP hole punching <br/> stp2pmessage message; <br/> message. imessagetype = p2ptrash; <br/> sendto (* pserversocket, (const char *) & message, sizeof (Message), 0 ,( Const sockaddr *) & serveraddr, sizeof (serveraddr); </P> <p> break; <br/>}< br/> case p2pmessageack: <br/>{< br/> // response to message sending <br/> recvedack = true; <br/> break; <br/>}< br/> case p2ptrash: <br/>{< br/> // The Hole-hitting message sent by the other party, which is ignored. <Br/> // do nothing... <br/> printf ("Recv p2ptrash data/N"); <br/> break; <br/>}< br/> case getalluser: <br/>{< br/> int usercount; <br/> int fromlen = sizeof (serveraddr); <br/> int Iread = recvfrom (* pserversocket, (char *) & usercount, sizeof (INT), 0, (sockaddr *) & serveraddr, & fromlen); <br/> If (Iread <= 0) <br/>{< br/> throw exception ("Login error/N"); <br/>}</P> <p> clientlist. clear (); </P> <p> cout <"have" <us Ercount <"users logined server:" <Endl; <br/> for (INT I = 0; I <usercount; I ++) <br/> {<br/> stuserlistnode * node = new stuserlistnode; <br/> recvfrom (* pserversocket, (char *) node, sizeof (stuserlistnode), 0, (sockaddr *) & serveraddr, & fromlen); <br/> clientlist. push_back (node); <br/> cout <"username:" <node-> username <Endl; <br/> in_addr TMP; <br/> TMP. s_un.s_addr = htonl (node-> ip); <br/> cout <"userip:" <ine T_ntoa (TMP) <Endl; <br/> cout <"userport:" <node-> port <Endl; <br/> cout <"" <Endl; <br/>}< br/> break; <br/>}</P> <p> # include "stdafx. H "<br/> # include" mysocket. H "<br/> class cserversocket: Public cmysocket <br/>{< br/> Public: <br/> stuserlistnode getuser (const char * username ); <br/> int run (); <br/> PRIVATE: <br/> userlist m_userlist; <br/>}; </P> <p> stuserlistnode * cserversocket :: ge Tuser (const char * username) <br/>{< br/> for (userlist: iterator iter = m_userlist; iter! = M_userlist.end (); ++ ITER) <br/>{< br/> If (strcmp (* ITER)-> username, username) = 0) <br/> return * ITER; <br/>}</P> <p> throw exception ("not find this user "); <br/>}</P> <p> int cserversocket: Run () <br/>{< br/> try <br/> {<br/> // initwinsock (); </P> <p> // socket primaryudp; <br/> m_socket = mksock (sock_dgram); </P> <p> sockaddr_in local; <br/> Local. sin_family = af_inet; <br/> Local. sin_port = htons (server_port); <B R/> Local. sin_addr.s_addr = htonl (inaddr_any); <br/> int nresult = BIND (m_socket, (sockaddr *) & Local, sizeof (sockaddr )); <br/> If (nresult = socket_error) <br/> throw exception ("BIND error"); </P> <p> sockaddr_in sender; <br/> stmessage recvbuf; <br/> memset (& recvbuf, 0, sizeof (stmessage); </P> <p> // start the main loop. <br/> // The main cycle is responsible for the following: <br/> // 1. Read the Client Login and logout messages and record the customer list. <br/> // 2: forward customer P2P requests <br/> for (;) <br/>{< br/> int dwsende R = sizeof (sender); <br/> int ret = recvfrom (char *) & recvbuf, sizeof (stmessage), 0, (sockaddr *) & sender, & dwsender); <br/> If (Ret <= 0) <br/> {<br/> printf ("Recv error"); <br/> continue; <br/>}< br/> else <br/>{< br/> int messagetype = recvbuf. imessagetype; <br/> switch (messagetype) {/* process received user messages */<br/> case login: <br/>{< br/> // record the user information to the user list <br/> printf ("has a user login: % s/n ", recvbuf. message. Loginmember. username); <br/> stuserlistnode * currentuser = new stuserlistnode (); <br/> strcpy (currentuser-> username, recvbuf. message. loginmember. username); <br/> currentuser-> IP = ntohl (sender. sin_addr.s_un.s_addr); <br/> currentuser-> Port = ntohs (sender. sin_port); </P> <p> clientlist. push_back (currentuser); </P> <p> // send the logged-in customer information to the newly connected customer. <br/> int nodecount = (INT) clientlist. size (); <br/> sendto (const char *) & Nodecount, sizeof (INT), 0, (const sockaddr *) & sender, sizeof (sender); <br/> for (userlist: iterator useriterator = clientlist. begin (); <br/> useriterator! = Clientlist. end (); <br/> ++ useriterator) <br/>{< br/> sendto (const char *) (* useriterator), sizeof (stuserlistnode), 0, (const sockaddr *) & sender, sizeof (sender); <br/>}</P> <p> break; <br/>}< br/> case logout: <br/> {<br/> // Delete this customer information <br/> printf ("has a user logout: % s/n", recvbuf. message. logoutmember. username); <br/> userlist: iterator removeiterator = NULL; <br/> for (userlist: iterator useriterator = clien Tlist. Begin (); <br/> useriterator! = Clientlist. end (); <br/> ++ useriterator) <br/>{< br/> If (strcmp (* useriterator)-> username), recvbuf. message. logoutmember. username) = 0) <br/>{< br/> removeiterator = useriterator; <br/> break; <br/>}< br/> If (removeiterator! = NULL) <br/> clientlist. remove (* removeiterator); <br/> break; <br/>}< br/> case p2ptrans: <br/>{< br/> // a customer wants the server to send a hole-hitting message to another customer <br/> printf ("% s wants to P2P % S/N", inet_ntoa (sender. sin_addr), recvbuf. message. translatemessage. username); <br/> stuserlistnode node = getuser (recvbuf. message. translatemessage. username); // "to" <br/> sockaddr_in remote; <br/> remote. sin_family = af_inet; <br/> remote. sin_port = HTO NS (node. port); <br/> remote. sin_addr.s_addr = htonl (node. IP); </P> <p> in_addr TMP; <br/> TMP. s_un.s_addr = htonl (node. IP); <br/> printf ("the address is % s, and port is % d/N", inet_ntoa (TMP), node. port); </P> <p> stp2pmessage transmessage; <br/> transmessage. imessagetype = p2psomeonewanttocallyou; <br/> transmessage. istringlen = ntohl (sender. sin_addr.s_un.s_addr); <br/> transmessage. port = ntohs (sender. sin_port ); </P> <p> sendto (const char *) & transmessage, sizeof (transmessage), 0, (const sockaddr *) & remote, sizeof (remote )); </P> <p> break; <br/>}</P> <p> case getalluser: <br/>{< br/> int command = getalluser; <br/> sendto (const char *) & command, sizeof (INT), 0, (const sockaddr *) & sender, sizeof (sender )); </P> <p> int nodecount = (INT) clientlist. size (); <br/> sendto (const char *) & nodecount, sizeof (INT), 0, (const sockad Dr *) & sender, sizeof (sender); </P> <p> for (userlist: iterator useriterator = clientlist. Begin (); <br/> useriterator! = Clientlist. end (); <br/> ++ useriterator) <br/>{< br/> sendto (const char *) (* useriterator), sizeof (stuserlistnode), 0, (const sockaddr *) & sender, sizeof (sender); <br/>}< br/> break; <br/>}</P> <p >}< br/> catch (exception & E) <br/>{< br/> printf (E. getmessage (); <br/> return 1; <br/>}</P> <p> return 0; <br/>}</P> <p> # ifndef _ message_h _ <br/> # DEFINE _ message_h _ </P> <p> # include <list> <br /> using namespace STD; </P> <p> Enum msg_type <br/> {<br/>/* Control Message */<br/> login_msg, <br/> logout_msg, <br/> p2ptrans_msg, <br/> getuser_msg, <br/>/* Data message */<br/> data_msg <br/> }; </P> <p> struct stloginmessage <br/> {<br/> char username [10]; <br/> char password [10]; <br/> }; <br/> // message sent when the client logs out <br/> struct stlogoutmessage <br/>{< br/> char username [10]; <br/> }; </P> <p> // client requests another client (username) from the server) send a UDP injection message to the user <br/> struct stp2ptranslate <br/>{< br/> char username [10]; <br/> }; </P> <p> // customer node Information <br/> struct stuserlistnode <br/> {<br/> char username [10]; <br/> unsigned int IP address; <br/> unsigned short port; <br/> }; </P> <p> Union msg_body <br/> {<br/> stloginmessage loginmember; <br/> stlogoutmessage logoutmember; <br/> stp2ptranslate translatemessage; <br/> stuserlistnode user; <br/>}; </P> <p> struct stmessage <br/>{< br/> msg_type msgtype; <br/> msg_body msgbody; <br/> }; </P> <p> // ================================== ========< br/> // The following protocols are used for communication between clients <br/> /// ============== ========================================< br/> # define p2pmessage 100 // send a message <br/> # define p2pmessageack 101 // response to the message received <br/> # define p2psomeonewanttocallyou 102 // message sent from the server to the client <br/> // you want the client to send a UDP hole package <br/> # define p2ptrash 103 // The hole stuffing package sent by the client, the receiving end should ignore this message </P> <p> // Message format sent between clients <br/> struct stp2pmessage <br/>{< br/> int imessagetype; <br/> int istringlen; // or IP address <br/> unsigned short port; <br/>}; </P> <p> using namespace STD; <br/> typedef list <stuserlistnode *> userlist; </P> <p> # endif </P> <p> # ifndef _ prediction_h _ <br/> # DEFINE _ prediction_h _ </P> <p> # define prediction_message_maxlen 256 <br/> # include "string. H "</P> <p> class exception <br/> {<br/> PRIVATE: <br/> char m_exceptionmessage [exception_message_maxlen]; <br/> public: <br/> exception (char * MSG) <br/>{< br/> strncpy (m_exceptionmessage, MSG, exception_message_maxlen ); <br/>}</P> <p> char * getmessage () <br/>{< br/> return m_exceptionmessage; <br/>}< br/> }; </P> <p> # endif </P> <p>

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.