Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Приложение Б. blocksock.cpp (CBlockingSocketException, CBlockingSocket, CHttpBlockingSocket)



blocksock.cpp (CBlockingSocketException, CBlockingSocket, CHttpBlockingSocket)

#include <stdafx.h>

#include "blocksock.h"

// Class CBlockingSocketException

IMPLEMENT_DYNAMIC(CBlockingSocketException, CException)

CBlockingSocketException::CBlockingSocketException(char* pchMessage)

{

m_strMessage = pchMessage;

m_nError = WSAGetLastError();

}

BOOL CBlockingSocketException::GetErrorMessage(LPTSTR lpstrError, UINT nMaxError,

PUINT pnHelpContext /*= NULL*/)

{

char text[200];

if(m_nError == 0) {

wsprintf(text, "%s error", (const char*) m_strMessage);

}

else {

wsprintf(text, "%s error #%d", (const char*) m_strMessage, m_nError);

}

strncpy(lpstrError, text, nMaxError - 1);

return TRUE;

}

// Class CBlockingSocket

IMPLEMENT_DYNAMIC(CBlockingSocket, CObject)

void CBlockingSocket::Cleanup()

{

// doesn't throw an exception because it's called in a catch block

if(m_hSocket == NULL) return;

VERIFY(closesocket(m_hSocket)!= SOCKET_ERROR);

m_hSocket = NULL;

}

void CBlockingSocket::Create(int nType /* = SOCK_STREAM */)

{

ASSERT(m_hSocket == NULL);

if((m_hSocket = socket(AF_INET, nType, 0)) == INVALID_SOCKET) {

throw new CBlockingSocketException("Create");

}

}

void CBlockingSocket::Bind(LPCSOCKADDR psa)

{

ASSERT(m_hSocket!= NULL);

if(bind(m_hSocket, psa, sizeof(SOCKADDR)) == SOCKET_ERROR) {

throw new CBlockingSocketException("Bind");

}

}

void CBlockingSocket::Listen()

{

ASSERT(m_hSocket!= NULL);

if(listen(m_hSocket, 5) == SOCKET_ERROR) {

throw new CBlockingSocketException("Listen");

}

}

BOOL CBlockingSocket::Accept(CBlockingSocket& sConnect, LPSOCKADDR psa)

{

ASSERT(m_hSocket!= NULL);

ASSERT(sConnect.m_hSocket == NULL);

int nLengthAddr = sizeof(SOCKADDR);

sConnect.m_hSocket = accept(m_hSocket, psa, &nLengthAddr);

if(sConnect == INVALID_SOCKET) {

// no exception if the listen was canceled

if(WSAGetLastError()!= WSAEINTR) {

throw new CBlockingSocketException("Accept");

}

return FALSE;

}

return TRUE;

}

void CBlockingSocket::Close()

{

if (NULL == m_hSocket)

return;

if(closesocket(m_hSocket) == SOCKET_ERROR) {

// should be OK to close if closed already

throw new CBlockingSocketException("Close");

}

m_hSocket = NULL;

}

void CBlockingSocket::Connect(LPCSOCKADDR psa)

{

ASSERT(m_hSocket!= NULL);

// should timeout by itself

if(connect(m_hSocket, psa, sizeof(SOCKADDR)) == SOCKET_ERROR) {

throw new CBlockingSocketException("Connect");

}

}

int CBlockingSocket::Write(const char* pch, const int nSize, const int nSecs)

{

int nBytesSent = 0;

int nBytesThisTime;

const char* pch1 = pch;

do {

nBytesThisTime = Send(pch1, nSize - nBytesSent, nSecs);

nBytesSent += nBytesThisTime;

pch1 += nBytesThisTime;

} while(nBytesSent < nSize);

return nBytesSent;

}

int CBlockingSocket::Send(const char* pch, const int nSize, const int nSecs)

{

ASSERT(m_hSocket!= NULL);

// returned value will be less than nSize if client cancels the reading

FD_SET fd = {1, m_hSocket};

TIMEVAL tv = {nSecs, 0};

if(select(0, NULL, &fd, NULL, &tv) == 0) {

throw new CBlockingSocketException("Send timeout");

}

int nBytesSent;

if((nBytesSent = send(m_hSocket, pch, nSize, 0)) == SOCKET_ERROR) {

throw new CBlockingSocketException("Send");

}

return nBytesSent;

}

int CBlockingSocket::Receive(char* pch, const int nSize, const int nSecs)

{

ASSERT(m_hSocket!= NULL);

FD_SET fd = {1, m_hSocket};

TIMEVAL tv = {nSecs, 0};

if(select(0, &fd, NULL, NULL, &tv) == 0) {

throw new CBlockingSocketException("Receive timeout");

}

int nBytesReceived;

if((nBytesReceived = recv(m_hSocket, pch, nSize, 0)) == SOCKET_ERROR) {

throw new CBlockingSocketException("Receive");

}

return nBytesReceived;

}

int CBlockingSocket::ReceiveDatagram(char* pch, const int nSize, LPSOCKADDR psa, const int nSecs)

{

ASSERT(m_hSocket!= NULL);

FD_SET fd = {1, m_hSocket};

TIMEVAL tv = {nSecs, 0};

if(select(0, &fd, NULL, NULL, &tv) == 0) {

throw new CBlockingSocketException("Receive timeout");

}

// input buffer should be big enough for the entire datagram

int nFromSize = sizeof(SOCKADDR);

int nBytesReceived = recvfrom(m_hSocket, pch, nSize, 0, psa, &nFromSize);

if(nBytesReceived == SOCKET_ERROR) {

throw new CBlockingSocketException("ReceiveDatagram");

}

return nBytesReceived;

}

int CBlockingSocket::SendDatagram(const char* pch, const int nSize, LPCSOCKADDR psa, const int nSecs)

{

ASSERT(m_hSocket!= NULL);

FD_SET fd = {1, m_hSocket};

TIMEVAL tv = {nSecs, 0};

if(select(0, NULL, &fd, NULL, &tv) == 0) {

throw new CBlockingSocketException("Send timeout");

}

int nBytesSent = sendto(m_hSocket, pch, nSize, 0, psa, sizeof(SOCKADDR));

if(nBytesSent == SOCKET_ERROR) {

throw new CBlockingSocketException("SendDatagram");

}

return nBytesSent;

}

void CBlockingSocket::GetPeerAddr(LPSOCKADDR psa)

{

ASSERT(m_hSocket!= NULL);

// gets the address of the socket at the other end

int nLengthAddr = sizeof(SOCKADDR);

if(getpeername(m_hSocket, psa, &nLengthAddr) == SOCKET_ERROR) {

throw new CBlockingSocketException("GetPeerName");

}

}

void CBlockingSocket::GetSockAddr(LPSOCKADDR psa)

{

ASSERT(m_hSocket!= NULL);

// gets the address of the socket at this end

int nLengthAddr = sizeof(SOCKADDR);

if(getsockname(m_hSocket, psa, &nLengthAddr) == SOCKET_ERROR) {

throw new CBlockingSocketException("GetSockName");

}

}

//static

CSockAddr CBlockingSocket::GetHostByName(const char* pchName, const USHORT ushPort /* = 0 */)

{

hostent* pHostEnt = gethostbyname(pchName);

if(pHostEnt == NULL) {

throw new CBlockingSocketException("GetHostByName");

}

ULONG* pulAddr = (ULONG*) pHostEnt->h_addr_list[0];

SOCKADDR_IN sockTemp;

sockTemp.sin_family = AF_INET;

sockTemp.sin_port = htons(ushPort);

sockTemp.sin_addr.s_addr = *pulAddr; // address is already in network byte order

return sockTemp;

}

//static

const char* CBlockingSocket::GetHostByAddr(LPCSOCKADDR psa)

{

hostent* pHostEnt = gethostbyaddr((char*) &((LPSOCKADDR_IN) psa)

->sin_addr.s_addr, 4, PF_INET);

if(pHostEnt == NULL) {

throw new CBlockingSocketException("GetHostByAddr");

}

return pHostEnt->h_name; // caller shouldn't delete this memory

}

// Class CHttpBlockingSocket

IMPLEMENT_DYNAMIC(CHttpBlockingSocket, CBlockingSocket)

CHttpBlockingSocket::CHttpBlockingSocket()

{

m_pReadBuf = new char[nSizeRecv];

m_nReadBuf = 0;

}

CHttpBlockingSocket::~CHttpBlockingSocket()

{

delete [] m_pReadBuf;

}

int CHttpBlockingSocket::ReadHttpHeaderLine(char* pch, const int nSize, const int nSecs)

// reads an entire header line through CRLF (or socket close)

// inserts zero string terminator, object maintains a buffer

{

int nBytesThisTime = m_nReadBuf;

int nLineLength = 0;

char* pch1 = m_pReadBuf;

char* pch2;

do {

// look for lf (assume preceded by cr)

if((pch2 = (char*) memchr(pch1, '\n', nBytesThisTime))!= NULL) {

ASSERT((pch2) > m_pReadBuf);

ASSERT(*(pch2 - 1) == '\r');

nLineLength = (pch2 - m_pReadBuf) + 1;

if(nLineLength >= nSize) nLineLength = nSize - 1;

memcpy(pch, m_pReadBuf, nLineLength); // copy the line to caller

m_nReadBuf -= nLineLength;

memmove(m_pReadBuf, pch2 + 1, m_nReadBuf); // shift remaining characters left

break;

}

pch1 += nBytesThisTime;

nBytesThisTime = Receive(m_pReadBuf + m_nReadBuf, nSizeRecv - m_nReadBuf, nSecs);

if(nBytesThisTime <= 0) { // sender closed socket or line longer than buffer

throw new CBlockingSocketException("ReadHeaderLine");

}

m_nReadBuf += nBytesThisTime;

}

while(TRUE);

*(pch + nLineLength) = '\0';

return nLineLength;

}

int CHttpBlockingSocket::ReadHttpResponse(char* pch, const int nSize, const int nSecs)

// reads remainder of a transmission through buffer full or socket close

// (assume headers have been read already)

{

int nBytesToRead, nBytesThisTime, nBytesRead = 0;

if(m_nReadBuf > 0) { // copy anything already in the recv buffer

memcpy(pch, m_pReadBuf, m_nReadBuf);

pch += m_nReadBuf;

nBytesRead = m_nReadBuf;

m_nReadBuf = 0;

}

do { // now pass the rest of the data directly to the caller

nBytesToRead = min(nSizeRecv, nSize - nBytesRead);

nBytesThisTime = Receive(pch, nBytesToRead, nSecs);

if(nBytesThisTime <= 0) break; // sender closed the socket

pch += nBytesThisTime;

nBytesRead += nBytesThisTime;

}

while(nBytesRead <= nSize);

return nBytesRead;

}





Дата публикования: 2014-11-29; Прочитано: 309 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.021 с)...