⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplesocket.cpp

📁 email收发软件例子源代码
💻 CPP
字号:
// SimpleSocket.cpp -- CSocket class plus TimeOut
//

#include "stdafx.h"
#include "SimpleSocket.h"
#include <process.h> // This is for _beginthread

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNAMIC(CSimpleSocket, CSocket)

CSimpleSocket::CSimpleSocket(UINT uTimeOut)
    : m_uTimeOut(uTimeOut)
{
}

CSimpleSocket::~CSimpleSocket()
{
}


int CSimpleSocket::ReceiveLine(CString& szLine, int nFlags)
{
    int nRet = 0;
    if (m_szFullString.IsEmpty()) {
	    nRet = ReceiveString(m_szFullString, nFlags);
    }
    // Return next line in string
    int nPos = m_szFullString.Find("\r\n");
    if (nPos==-1) {
        szLine = m_szFullString;
    } else {
        szLine = m_szFullString.Left(nPos+1);
        m_szFullString = m_szFullString.Mid(nPos+2);
    }
    TRACE1("CSimpleSocket::ReceiveLine: \"%s\"\n", (LPCTSTR)szLine);
    return(szLine.GetLength());
}


int CSimpleSocket::ReceiveString(CString& str, int nFlags)
{
	static char szBuf[4096];
	memset(szBuf, 0, sizeof(szBuf));

	// Call generic-buffer function
	int nRet = Receive((void *)szBuf, sizeof(szBuf), nFlags);

    if (nRet==0) {
        // Connection has been closed (?)
        nRet=SOCKET_ERROR;
        SetLastError(WSAECONNRESET);
    }

	// Fill in the CString reference
	str = szBuf;
    TRACE1("CSimpleSocket::ReceiveString: \"%s\"\n", (LPCTSTR)str);
	return nRet;
}

int CSimpleSocket::Receive(void* lpBuf, int nBufLen, int nFlags)
{
	int nResult = 0;

    nResult = WaitForData(&m_hSocket, NULL, &m_hSocket);
    if (nResult != SOCKET_ERROR) {

        nResult = CSocket::Receive(lpBuf, nBufLen, nFlags);

    }

	return(nResult);
}

int CSimpleSocket::Send(LPCTSTR lpszString, int nFlags)
{
    CString szString = lpszString;

    // Use CString version of Send
    return(Send(szString, nFlags));
}

int CSimpleSocket::Send(CString &szString, int nFlags)
{
    // Use void* buffer version of Send
    return(Send((void *)szString.GetBuffer(0), szString.GetLength(), nFlags));
}

int CSimpleSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
{
	int nResult = 0;

    nResult = WaitForData(NULL, &m_hSocket, &m_hSocket);
    if (nResult != SOCKET_ERROR) {

        nResult = CSocket::Send(lpBuf, nBufLen, nFlags);

    }

	return(nResult);
}

void CSimpleSocket::SetTimeOut(UINT uTimeOut)
{
    m_uTimeOut = uTimeOut;
}

UINT CSimpleSocket::GetTimeOut() const
{
    return(m_uTimeOut);
}

int CSimpleSocket::WaitForData(SOCKET *pSocketForReceiving, SOCKET *pSocketForSending,SOCKET *pSocketForExceptions)
{
    int nSocketsReady = 0;
    fd_set FdSetReceive;
    FD_ZERO(&FdSetReceive);
    fd_set FdSetSend;
    FD_ZERO(&FdSetSend);
    fd_set FdSetError;
    FD_ZERO(&FdSetError);

    if (pSocketForReceiving) {
        FD_SET(*pSocketForReceiving, &FdSetReceive);
    }
    if (pSocketForSending) {
        FD_SET(*pSocketForSending, &FdSetSend);
    }
    if (pSocketForExceptions) {
        FD_SET(*pSocketForExceptions, &FdSetError);
    }

    TIMEVAL tv;
    TIMEVAL *ptv;

    if (m_uTimeOut) {
        tv.tv_sec = m_uTimeOut/1000;
        tv.tv_usec = m_uTimeOut*1000 - tv.tv_sec * 1000000;
        ptv = &tv;
    } else {
        ptv = NULL; // NULL for blocking operation (never times out)
    }

    nSocketsReady = select(0, &FdSetReceive, &FdSetSend, &FdSetError, ptv);

 	// If the operation timed out, set a more
	// natural error message
    if (nSocketsReady == 0) {
		SetLastError(WSAETIMEDOUT);
        nSocketsReady = SOCKET_ERROR;
    }

    return(nSocketsReady);
}

BOOL CSimpleSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort, UINT uTimeOut)
{
    BOOL bReturnCode = FALSE;
    DWORD dwWaitStatus;
    HANDLE lpWaitHandles = NULL;
    SOCKET hSocket = INVALID_SOCKET;
    HANDLE hConnectingThread = NULL;
    DWORD dwConnectionErrorCode = 0;

    // TODO: handle connect timer/timeout for other Connect method:
    //                BOOL Connect( const SOCKADDR* lpSockAddr, int nSockAddrLen );
    void *pvIOParams[] = {
        (char *)lpszHostAddress,
        (char *)&nHostPort,
        (char *)&hSocket,
        (char *)&dwConnectionErrorCode
    };

    // Create 1 thread to make the connection
    hConnectingThread = CreateConnectingThread((void *)pvIOParams);

    if (!hConnectingThread) {
        // Cannot create thread, and GetLastError() will return the error code
        return(FALSE);
    }
    lpWaitHandles = hConnectingThread;

    // Wait for thread to end (connection established) or for time-out
    dwWaitStatus = WaitForSingleObject(lpWaitHandles, (DWORD)uTimeOut);

    switch (dwWaitStatus) {
    case WAIT_ABANDONED:
        break;
    case WAIT_TIMEOUT:
        // Timeout occurred: Kill connecting thread and return error (WSAETIMEDOUT)
        if (hConnectingThread) {
            TerminateThread(hConnectingThread, (DWORD)HRESULT_FROM_WIN32(WSAETIMEDOUT));
        }
        // We must set the timeout error in current thread
        WSASetLastError(WSAETIMEDOUT);
        bReturnCode = FALSE;
        break;
    case WAIT_OBJECT_0:   // Thread 1: Connecting thread
        // Connection established or error?
        if (dwConnectionErrorCode == 0) {
            // Connection established: attach connected socket to 'this'
            if (m_hSocket != INVALID_SOCKET) {
                Close();
            }
            Attach(hSocket);
            bReturnCode = TRUE;
        } else {
            // Connection failure: report error
            WSASetLastError(dwConnectionErrorCode);
            bReturnCode = FALSE;
        }
        break;
    case 0xFFFFFFFF:
        // Wait failure: abnormal
        break;
    default:
        // Unexpected: error
        break;
    }

    return(bReturnCode);
}

HANDLE CSimpleSocket::CreateConnectingThread(void *pvIOParams)
{
    HANDLE hThread = NULL;

    hThread = reinterpret_cast<HANDLE> (_beginthread(ThreadConnectSocket, 0, (void *)pvIOParams));

    return(hThread);
}

void CSimpleSocket::ThreadConnectSocket(void *pvIOParams)
{
    LPCTSTR lpszHostAddress = NULL;
    UINT *puHostPort = NULL;
    SOCKET *phSocket = NULL;
    DWORD *pdwConnectionErrorCode = NULL;

    // Really really dirty cast but how can you pass 4 pointers within a (void *)?
    int *piIOParams = (int *)pvIOParams;
    void *pIOParams[4] = {
        (void *)piIOParams[0],
        (void *)piIOParams[1],
        (void *)piIOParams[2],
        (void *)piIOParams[3]
    };


    if (pIOParams) {
        lpszHostAddress = (LPCTSTR)pIOParams[0];
        puHostPort = (UINT *)pIOParams[1];
        phSocket = (SOCKET *)pIOParams[2];
        pdwConnectionErrorCode = (DWORD *)pIOParams[3];

        if (lpszHostAddress && puHostPort) {
            CSocket oConnectingSocket;
            if (oConnectingSocket.Create()) {
                if (oConnectingSocket.Connect(lpszHostAddress, *puHostPort)) {
                    if (phSocket) {
                        *phSocket = oConnectingSocket.Detach();
                    }
                    if (pdwConnectionErrorCode) {
                        *pdwConnectionErrorCode = 0;
                    }
                } else {
                    if (pdwConnectionErrorCode) {
                        *pdwConnectionErrorCode = GetLastError();
                    }
                }
            } else {
                if (pdwConnectionErrorCode) {
		            *pdwConnectionErrorCode = oConnectingSocket.GetLastError();
                }
	        } 
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -