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>