Encapsate Socket (Update)

xiaoxiao2021-04-04  251

CasyNsocket seems to meet the requirements, can't be used across threads should be its fatal injuries, using Socket is the best way, which is also recommended by many big cows. In order to avoid duplication of labor, I have encapsulated a CMYSocket class, I hope to use like CasyNsocket (it is not possible now, even beginners, only slowly improve, maybe a day can be close to casynsocket), since it is a class of packages, Thread safety has been calculated, huh, huh.

The following functions are currently implemented:

Create Socket, Data Receiving (TCP, and UDP), send and receive buffer size settings.

The IO model uses a WSAEventSelect mechanism.

Use it to realize the chat program of the LAN, very easy to use. If there is an inappropriate place, please leave a message, I will gradually improve it!

Instructions:

Inherit the CMYSocket class, overload onconcept, onReceive and other functions (same as the CasyncSocket method). Don't call the AFXSocketinit function, because the function is working in the code I packaged.

Below is the code

***************************** Head file mysocket.h ************** ******** #ifndef __MYSOCKET_H __ # define __MYSOCKET_H__ #include #define MAX_SOCKET 64 #pragma comment (lib, "Ws2_32.lib") typedef struct tagClient {sockaddr addr; SOCKET sock;} TClient; class CMySocket {public: CMySocket (); CMySocket (const CMySocket &); ~ CMySocket (); static int StartUp (); int Create (int port, int socket_type, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE) ; Int Listen (int backlog = somaxconn); int access (cmysocket * psocket, struct sockaddr * addr); int connection (const char * ip, int port); int received (Char * buf, int LEN) INT Receive (Char * BUF, INT LEN, CHAR * IP, INT * Port); Int Se (Char * BUF, INT LEN); Int Se (Char * Buf, Int Len, Const Char * IP, INT Port); int GetRcvBufSize (int * bufsize, int * len); int GetSndBufSize (int * bufsize, int * len); int SetRcvBufSize (int * bufsize, int len); int SetSndBufSize (int * bufsize, int len); CMySocket operator = ( CMYSOCKET & MYSOCKET1); VIR tual void OnAccept (int errorcode); virtual void OnConnect (int errorcode); virtual void OnReceive (int errorcode); virtual void OnSend (int errorcode); virtual void OnClose (int errorcode); static void GetSocketAddr (struct sockaddr * addr); static void RemoveSocket (SOCKET s); SOCKET m_socket; int m_nSocketType; long m_lEvent; BOOL m_bThreadStarted; BOOL m_bEndTread; static int m_nClientNum; static TClient clientList [MAX_SOCKET]; static SOCKET socketArray [MAX_SOCKET]; static WSAEVENT eventArrray [MAX_SOCKET]; static int M_Totalsocket; static dword m_dwindex; static critical_section m_cs; protected: static int m_ninstnum; static bool m_bstartup; static bool m_binitcs; private:};

#ENDIF *************************** Code implements mysocket.cpp *************** ************* #include "stdafx.h" #include "mysocket.h" #include void socketthread (void * parm); tclient cmysocket :: ClientList [max_socket] ; SOCKET CMySocket :: socketArray [MAX_SOCKET]; WSAEVENT CMySocket :: eventArrray [MAX_SOCKET]; int CMySocket :: m_totalSocket = 0; int CMySocket :: m_nInstnum = 0; int CMySocket :: m_nClientNum = 0; DWORD CMySocket :: m_dwIndex = 0 ; BOOL CMySocket :: m_bStartUp = FALSE; BOOL CMySocket :: m_bInitCS = FALSE; CRITICAL_SECTION CMySocket :: m_cs; CMySocket :: CMySocket () {m_socket = INVALID_SOCKET; m_bThreadStarted = FALSE; m_bEndTread = FALSE; m_nInstnum ; if (! m_bInitCS) { InitializeCriticalSection (& m_cs); m_bInitCS = TRUE;}} CMySocket :: CMySocket (const CMySocket & myScoket) {m_socket = myScoket.m_socket; m_nSocketType = myScoket.m_nSocketType;} CMySocket :: ~ CMySocket () {m_nInstnum--; if (m_socket! = INVALID_SOCKET) {CloseSocket (m_socket);} if (! M_ nInstnum) {WSACleanup (); m_bStartUp = FALSE;}} int CMySocket :: StartUp () {if (m_bStartUp) {WSADATA wsaData;! if (WSAStartup (WINSOCK_VERSION, & wsaData)) {int err = WSAGetLastError (); return err; }} return 0;} int CMySocket :: Create (int port, int socket_type, long lEvent) {if {StartUp () (m_bStartUp!);} if (m_socket = INVALID_SOCKET!) {return 0;} m_nSocketType = socket_type; m_socket = socket (AF_INET, m_nSocketType, 0); if (m_socket == INVALID_SOCKET) {int err = WSAGetLastError (); return err;} else {sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.S_un.S_addr = INADDR_ANY;

addr.sin_port = htons (port); if (bind (m_socket, (LPSOCKADDR) & addr, sizeof (addr)) == SOCKET_ERROR) {int err = WSAGetLastError (); return err;}} WSAEVENT wsaEvent = WSACreateEvent (); if (WSAEventSelect (m_socket, wsaEvent, lEvent)) {int err = WSAGetLastError (); return err;} EnterCriticalSection (& m_cs); socketArray [m_totalSocket] = m_socket; eventArrray [m_totalSocket] = wsaEvent; m_totalSocket ; LeaveCriticalSection (& m_cs); m_bEndTread = False; if (_BeginThread, 0, this) == -1) {RETURN-1;} int loopnum = 0; while (! M_bthreadstarted) {loopNum ; if (loopnum> 200) {return -1;} SLEEP 10);} return 0;} int CMySocket :: Close () {RemoveSocket (m_socket); if (closesocket (m_socket) == SOCKET_ERROR) {int err = WSAGetLastError (); return err;} m_socket = INVALID_SOCKET; m_bEndTread = TRUE Return 0;} int CMYSocket :: Listen (INT Backlog) {if (Listen (m_socket, backlog) == Socket_ERROR) {int err = wsagetlasterror (); return err;} return 0;} int CMYSOCKET :: Acce pt (CMySocket * pSocket, struct sockaddr * addr) {SOCKET sock; int len ​​= sizeof (struct sockaddr); if ((sock = accept (m_socket, addr, & len)) == INVALID_SOCKET) {int err = WSAGetLastError (); return err;} pSocket-> m_socket = sock; pSocket-> m_nSocketType = SOCK_STREAM; WSAEVENT wsaEvent = WSACreateEvent (); if (WSAEventSelect (sock, wsaEvent, FD_READ | FD_CLOSE)) {int err = WSAGetLastError (); return err;} ENTERCRITILAY [M_TOTALSOCKET] = SOCK; EventArrray [m_totalsocket] = WSAEvent; M_Totalsocket ; int index = m_nclientnum;

clientList [index] .addr = * addr; clientList [index] .sock = sock; m_nClientNum ; LeaveCriticalSection (& m_cs); return 0;} int CMySocket :: Connect (const char * IP, int port) {sockaddr_in addr; addr. sin_family = AF_INET; addr.sin_addr.S_un.S_addr = inet_addr (IP); addr.sin_port = htons (port); if (connect (m_socket, (LPSOCKADDR) & addr, sizeof (addr)) == SOCKET_ERROR) {int err = Wsagetlasterror (); return err;} return 0;} void cmysocket :: removeSocket (socket s) {INT i, j; entercriticalsection (& m_cs); int totalsocket = m_totalsocket; for (i = 0; i m_bThreadStarted = TRUE; while ( 1) {EnterCriticalSection (& CMySocket :: m_cs); ret = WSAWaitForMultipleEvents (CMySocket :: m_totalSocket, CMySocket :: eventArrray, FALSE, timeout, FALSE); LeaveCriticalSection (& CMySocket :: m_cs); if (pMySocket-> m_bEndTread) {_endthread ( );} If (ret == WSA_WAIT_TIMEOUT) {Continue;} dwindex = ret;

dwIndex - = WSA_WAIT_EVENT_0; CMySocket :: m_dwIndex = dwIndex; memset (& tEvent, 0, sizeof (WSANETWORKEVENTS)); EnterCriticalSection (& CMySocket :: m_cs); WSAEnumNetworkEvents (CMySocket :: socketArray [dwIndex], CMySocket :: eventArrray [dwIndex], & tEvent); WSAResetEvent (CMySocket :: eventArrray [dwIndex]); LeaveCriticalSection (& CMySocket :: m_cs); if (tEvent.lNetworkEvents & FD_CONNECT) {errorcode = tEvent.iErrorCode [FD_CONNECT_BIT]; pMySocket-> OnConnect (errorcode);} else if (tEvent.lNetworkEvents & FD_ACCEPT) {errorcode = tEvent.iErrorCode [FD_ACCEPT_BIT]; pMySocket-> OnAccept (errorcode);} else if (tEvent.lNetworkEvents & FD_READ) {DWORD nBytes = 0; errorcode = tEvent.iErrorCode [FD_READ_BIT] ; ioctlsocket (CMySocket :: socketArray [dwIndex], FIONREAD, & nBytes); if (nBytes> 0) pMySocket-> OnReceive (errorcode);} else if (tEvent.lNetworkEvents & FD_WRITE) {errorcode = tEvent.iErrorCode [FD_WRITE_BIT]; PMYSOCKET-> Onsend (ErrorCode);} else if (TEVENT.LNETWORKEVENTS & FD _CLOSE) {errorcode = tEvent.iErrorCode [FD_CLOSE_BIT]; pMySocket-> OnClose (errorcode); CMySocket :: RemoveSocket (CMySocket :: socketArray [dwIndex]);} else {}}} int CMySocket :: Receive (char * buf, int len) {sockaddr addr; int size = sizeof (addr); switch (m_nSocketType) {case SOCK_DGRAM: if (recvfrom (m_socket, buf, len, 0, & addr, & size) == SOCKET_ERROR) {int err = WSAGetLastError () Return Err;} Break; Case Sock_Stream: IF (RECV (M_Socket, BUF, LEN, 0) == SOCKET_ERROR) {int err = wsagetlasterror (); return err;} Break; default: Break;} return;

} Int CMySocket :: Receive (char * buf, int len, char * IP, int * port) {sockaddr addr; int size = sizeof (addr); sockaddr_in * pAddr_in; switch (m_nSocketType) {case SOCK_DGRAM: if (recvfrom ( M_Socket, BUF, LEN, 0, & Addr, & size) == Socket_ERROR) {int err = wsagetlasterror (); return err;} Paddr_in = (sockaddr_in *) & addr; structdr; ip, inet_adoa (paddr_in-> sin_addr); * Port = NTOHS (PADDR_IN-> SIN_PORT); Break; Case Sock_Stream: IF (RECV (M_Socket, BUF, LEN, 0) == SOCKET_ERROR) {int err = wsagetlasterror (); return err;} Break; default: Break; Return 0;} int CMYSocket :: Send (Char * BUF, INT LEN) {IF (send (m_socket, buf, len, 0) == SOCKET_ERROR) {int err = wsagetlasterror (); return err;} returnography;} INT CMYSOCKET :: Send (Char * BUF, INT LEN, CONST Char * IP, INT port) {sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_un.s_addr = inet_addr (ip); addr.sin_port = htons Port); switch (m_nsockettype) {copy sock_dgram: IF (sendto (M_Socket, Buf, Len, 0, (LPSOCKADDR) & addr, sizeof (addr) == Socket_er RETURN ERR;} Break; Case Sock_Stream: IF (send (m_socket, buf, len, 0) == Socket_ERROR) {int err = wsagetlasterror (); returnal;} Break; default : break;} return 0;} int CMySocket :: GetRcvBufSize (int * bufsize, int * len) {if (getsockopt (m_socket, SOL_SOCKET, SO_RCVBUF, (char *) bufsize, len)) {int err = WSAGetLastError (); return err;} return 0;} int CMySocket :: GetSndBufSize (int * bufsize, int * len) {if (getsockopt (m_socket, SOL_SOCKET, SO_SNDBUF, (char *) bufsize, len)) {int err = WSAGetLastError (); Return Err;} Return 0;

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

New Post(0)