Introduction:
Cadmitsocket, derived from CSocket, which is added more than CSocket is the Socket connection after managing Accept, and redefines the Send function. Manage the received data and set the package, and then call the onRecResponse (lpbyte, int) virtual function after receiving the entire package data.
Use points:
The Socket you use must be derived from Cadmitsocket and overrto OnRecResponse (), OnsocketClose (). You may need to overload onacceptsocket (). among them:
OnRecResponse (): When a joint data is received, it is called.
ONACCEPTSOCKET (): Indicates that a client connection has been accept.
OnSocketClose (): When the Accepted Socket is closed, it and onacceptsocket () are just the opposite.
Your derived class (assuming to cmysocket) must declare Declare_DyncReate (CMYSocket) and Implement_DyncReate (CMYSocket, CadmitSocket).
CPACKHEAD is the header information, where the field:
Word m_packflag; // package flag, custom.
UINT M_PACKSIZE; / / Package length, including the length of the header length and data length
If you don't want to use this class, you can also refer to this source code to write your own socket code.
Additional:
About CSocket, CasyncSocket uses some of the attention, otherwise it will result in unnecessary trouble: 1. CSocket and its base class CasyncSocket use the Windows message mechanism, that is, the socket event is sent to the built-in window via the POST message, and in this window Call the virtual function onccept (), onConnect (), onsend (), onreceive (), and onclose (), so the thread where Csocket is located must have a message loop. 2. A CSocket object is not directly transmitted (pointer) when passing in multiple threads. Because CSocket is trying to design as thread security, its internal handle M_HSocket can only be owned by one thread at the same time. Therefore, the handle should be passed between the thread rather than the pointer. The method is: the thread currently has a CSocket object first Detach (), then passes the returned handle to another thread. In another thread, then attach (). 3. When using CSocket in multi-thread, please play SP5 for VS6.0. Because the SP5 and the SP5 are not hit, the source code of the AFXSockInit () function is different. The latter supports multithreading. And each of the threads used to CSocket, please call AFXSockInit () 4. For an onRecEacy () event, receive the arrival data of the socket internal buffer, otherwise onReceive () may no longer trigger. The reason is: onsend (), onRecEive () is triggered when the buffer is orientally triggered. 5, the default buffer size in Socket is generally 4096 or 8192, the default size characteristics are our concern, although it is not necessary to know how big, but they know that there is such a feature, so unless a communication You should send and receive information about the group (including the boundaries and signs of your own definition package).
Header file: admitsocket.h
#if! defined (AFX_ADMITSOCKET_H__68E0BD89_4E1E_48CB_B3E3_4235CED0C14B__INCLUDED _) # define AFX_ADMITSOCKET_H__68E0BD89_4E1E_48CB_B3E3_4235CED0C14B__INCLUDED_ # if _MSC_VER> 1000 # pragma once # endif // _MSC_VER> 1000
#include
#ifdef _afx_packing # Pragma Pack (push, _afx_packing) #ENDIF
// Socket Package Structure and Data Definition #define Listenport1 3210 // THALES Send Used Socket Port #define Listenport2 3215 / / The default port of the large-scale communication
Typedef struct cpackhead {word m_packflag; uint m_packsize;} cpackhead;
Class Cadmitsocket: Public Csocket {Declare_Dyncreate (Cadmitsocket) public: Cadmitsocket (); Virtual ~ Cadmitsocket ();
Virtual void oncceptsocket; Virtual Void OnSocketClose (); Virtual Void OnRecResponse (lpbyte, int);
Static CTypedPtrarray
Bool Listen (int nport = 0); Virtual Void onaccept (int NerrorCode);
Virtual void close ();
BOOL M_BLISTEN;
Bool Connect (lpctstr lpszhostaddress, uint nhostport = 0); Bool Send (Word NPackflag, Const Void * lpbuf, int NBUFLEN);
public: // ClassWizard generated virtual function overrides // {{AFX_VIRTUAL (CAdmitSocket) public: virtual void OnReceive (int nErrorCode); virtual void OnClose (int nErrorCode); //}} AFX_VIRTUAL
// generated message mapp functions // {{AFX_MSG (Cadmitsocket) // Note - The classwizard will add and remove member functions here. //}} AFX_MSG
//MplementationProtace: uint m_nbufsize; lpbyte m_precdatabuf; uint m_nprevdataasize; // cpackhead m_packhead;};
Inline void Cadmitsocket :: OnRecResponse (lpbyte, int) {}
Inline void Cadmitsocket :: onacceptsocket (Cadmitsocket * pacceptsock) {}
Inline void Cadmitsocket :: OnsetClose () {}
#ifdef _afx_packing # polyma pack (POP) #ENDIF
// {{AFX_INSERT_LOCATION}} // Microsoft Visual C Will Insert Additional Declarations Immediately Before The Previous Line.
#ENDIF / /! Defined (AFX_ADMITSOCKET_H__68E0BD89_4E1E_48CB_B3E3_4235CED0C14B__included_)
Executive file: admitsocket.cpp
#include "stdafx.h" #include "admitsocket.h"
#ifdef _debug # define new debug_new # undef this_filestatic char this_file [] = __file __; # ENDIF
// # Define recbuf_size 10000
Implement_dyncreate (Cadmitsocket, CSocket)
CtypedPtrarray
Cadmitsocket :: Cadmitsocket (): m_precdatabuf (null), m_nprevdataasize (0) {m_blisten = false; m_nbufsize = 0;}
Cadmitsocket :: ~ cadmitsocket () {if (m_hsocket! = Invalid_socket) csocket :: close (); if (m_precdatabuf! = Null) {delete [] m_precdatabuf; m_precdatabuf = null;}
// Do not edit the following lines, which are needed by ClassWizard. # If 0BEGIN_MESSAGE_MAP (CAdmitSocket, CSocket) // {{AFX_MSG_MAP (CAdmitSocket) //}} AFX_MSG_MAPEND_MESSAGE_MAP () # endif // 0
Void Cadmitsocket :: OnReceive (int NerrorCode) // Server side receive {if (NerrorCode! = 0) {assert (false);}
int nRec; DWORD dwBytes = 0; CPackHead * pPackHead; UINT nOffset = 0, nHeadSize = sizeof (CPackHead); if (! IOCtl (FIONREAD, & dwBytes)) {dwBytes = GetLastError (); if (dwBytes == WSAENETDOWN || dwBytes == WSAENOTSOCK) Close (); return;} if (dwBytes == 0) {ASSERT (FALSE); return;} if (dwBytes m_nPrevDataSize> m_nBufSize) {LPBYTE pTmpBuf = new BYTE [dwBytes m_nPrevDataSize]; if (m_pRecDataBuf ! = NULL) {memcpy (pTmpBuf, m_pRecDataBuf, m_nPrevDataSize); delete [] m_pRecDataBuf;} m_pRecDataBuf = pTmpBuf; m_nBufSize = dwBytes m_nPrevDataSize;} nRec = Receive (m_pRecDataBuf m_nPrevDataSize, dwBytes); if (nRec <= 0) { Close (); return;} m_nPrevDataSize = nRec; while (m_nPrevDataSize> nHeadSize) {pPackHead = (CPackHead *) (m_pRecDataBuf nOffset); if (m_nPrevDataSize
TRACE (_T ( "OnReceive (), is ready to receive: / n")); int nPackSize, nHeadSize = sizeof (m_PackHead); int nRecCount = Receive (& m_PackHead, nHeadSize); if (nRecCount == 0 || nRecCount == SOCKET_ERROR ) {Close (); assert (false); return;} trace (_t ("Start Receive% D byte / N"), NRECCOUNT); NPACKSIZE = NRECCOUNT; while (NPacksize LPBYTE pDataBuf = new BYTE [m_PackHead.m_PackSize]; memcpy (pDataBuf, (char *) & m_PackHead, nHeadSize); while ((UINT) nPackSize / * If (NerrorCode! = 0) Return; INT NPACKSIZE, NRECCOUNT; DWORD NBYTES = 0; if (m_nprevdatasize == 0) {CPackhead PHS; INT NHEADSIZE = SizeOf (PHS); if (! Ioctl (fionread, & nbytes) | | NBYTES <(dword) nheadsize // check how many bytes retrodun; nReccount = receive (& phs, nheadsize, msg_peek); if (nreccount == 0 || nRcount == Socket_ERROR) // The connection has been closed {onClose 0); return;} if (nRecCount = nHeadSize) // header length not return;! nPackSize = phs.m_PackSize; if (m_pRecDataBuf == NULL) m_pRecDataBuf = (BYTE *) malloc (nPackSize); else m_pRecDataBuf = (BYTE * ) realloc (m_pRecDataBuf, nPackSize);} else {nPackSize = ((CPackHead *) m_pRecDataBuf) -> m_PackSize; if (m_nPrevDataSize> = nPackSize) // should never happen {m_nPrevDataSize = 0; return;}} nRecCount = Receive (m_pRecDataBuf m_nPrevDataSize, nPackSize - m_nPrevDataSize); if (nRecCount == 0 || nRecCount == SOCKET_ERROR) // connection is closed {OnClose (0); return;} m_nPrevDataSize = nRecCount; if (m_nPrevDataSize ==NPACKSIZE) {// if (s_pprocrespsock! = null) // If this Socket is in the sub-thread, then the following response function is located other threads, this requires thread synchronization // s_pprocRespsock (this, m_precdatabuf, npacksize); OnRecResponse (m_precdatabuf, npacksize); m_nprevdatasize = 0; free (m_precdatabuf); m_precdatabuf = null; if (ioctl (fionread, & nbytes) && nbytes> 0) OnRecEates (0);} * /} Void Cadmitsocket :: OnClose (int NerrorCode) {close (); BOOL CAdmitSocket :: Listen (int nPort) {if (nPort == 0) nPort = LISTENPORT1; if (m_hSocket == INVALID_SOCKET && Create (nPort)!) Return FALSE; return (m_bListen = CSocket :: Listen (0x7fffffff)); } void CAdmitSocket :: OnAccept (int nErrorCode) {CAdmitSocket * psockit = (CAdmitSocket *) this-> GetRuntimeClass () -> CreateObject (); ASSERT (! psockit = NULL); if (! Accept (* psockit)) delete psockit ; S_sockArray.Add (psockit); onacceptsocket (psockit); csocket :: onaccept (nerrorcode);} Void Cadmitsocket :: Close () {// DWORD NBYTES = 0; // ioctl (fionread, & nbytes); CSocket :: close (); int i, ncount = s_sockArray.getsize (); if (m_blisten) {for (i = 0; i BOOL CAdmitSocket :: Connect (LPCTSTR lpszHostAddress, UINT nHostPort) {if (! M_hSocket == INVALID_SOCKET && Create ()) return false; if (nHostPort == 0) nHostPort = LISTENPORT1; if (CSocket :: Connect (lpszHostAddress, nHostPort! )) {IF (getLastError ()! = Wsaewouldblock) Return False;} return true;