Red de conocimiento informático - Problemas con los teléfonos móviles - Programación de sockets ~~Urgente~~~

Programación de sockets ~~Urgente~~~

Clase de descarga HTTP encapsulada por socket

//HttpDownload.h

#ifndef _HTTPDOWNLOAD_H

#define _HTTPDOWNLOAD_H

//#include "InitSock.h"

//CInitSock estático initsock;

/****************** * ************************************************** ****

Descripción: clase de codificación y decodificación Base64

Función: se puede utilizar para resolver: 81/index.html#link1

///

//////////////////////////////////////////// ///// //////////////////

// Buscar si hay un número de puerto

nPos = strTemp. Find(":");

if( nPos == -1 )

{

strServer = strTemp;

nPort = CHttpDownload::DEFAULT_PORT;

}

else

{

strServer = strTemp.Left( nPos );

strTemp = strTemp.Mid( nPos+1 );

nPort = _ttoi((LPCTSTR)strTemp);

}

devuelve verdadero;

}

#endif

//HttpDownload.cpp

#include "StdAfx.h"

#include "HttpDownload.h"

/*************************************** *********** ****************************

***** ************* ************************************* ************** ******/

int CBase64::s_nBase64Mask[] = {0, 1, 3, 7, 15, 31, 63 , 127, 255};

CString CBase64::s_strBase64TAB = _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");

int CBase64::Base64Decode(LPCTSTR lpszDecoding, CString& strDecoded)

{

int nIndex = 0;

int nDigit;

int nDecode[ 256 ];

int nSize;

int nNumBits = 6;

if( lpszDecoding == NULL )

devuelve 0;

if(

( nSize = lstrlen(lpszDecoding) ) == 0 )

return 0;

// Construir tabla de decodificación

for( int i = 0; i < 256; i++ )

nDecode[i] = -2; // Dígito ilegal

for( i=0; i < 64; i++ )

{

nDecode[ s_strBase64TAB[ i ] ] = i;

nDecode[ '=' ] = -1

}

/ / Borrar el buffer de salida

strDecoded = _T("");

long lBitsStorage =0;

int nBitsRemaining = 0;

int nScratch = 0;

UCHAR c;

// Decodifica la entrada

for( nIndex = 0, i = 0; nIndex < nSize; nIndex++ )

{

c = lpszDecoding[ nIndex ];

// Ignora todos los caracteres ilegales

if( c> 0x7F )

continuar;

nDigit = nDecode[c];

if( nDigit >= 0 )

{

lBitsStorage = (lBitsStorage << nNumBits) | (nDigit & 0x3F);

nBitsRemaining += nNumBits;

while( nBitsRemaining > 7 )

{

nScratch = lBitsStorage >> (nBitsRemaining - 8);

strDecoded += (nScratch & 0xFF);

i++;

nBitsRemaining -= 8;

}

}

}

return strDecoded.GetLength();

}

int CBase64::Base64Encode(LPCTSTR lpszEncoding, CString& strEncoded)

{

int nDigit;

int nNumBits = 6 ;

int nIndex = 0;

int nInputSize;

strEncoded = _T( "" );

if( lpszEncoding == NULL )

devuelve 0;

if( ( nInputSize = lstrlen(lpszEncoding) ) == 0 )

devuelve 0;

int nBitsRemaini

ng = 0;

long lBitsStorage = 0;

long lScratch = 0;

int nBits;

UCHAR c; p>

while( nNumBits > 0 )

{

while( ( nBitsRemaining < nNumBits ) && ( nIndex < nInputSize ) )

{

c = lpszEncoding[ nIndex++ ];

lBitsStorage <<= 8;

lBitsStorage |= (c & 0xff);

nBitsRemaining + = 8;

}

if( nBitsRemaining < nNumBits )

{

lScratch = lBitsStorage << ( nNumBits - nBitsRemaining

nBits = nBitsRemaining;

nBitsRemaining = 0;

}

else

{

lScratch = lBitsStorage >> ( nBitsRemaining - nNumBits );

nBits = nNumBits;

nBitsRemaining -= nNumBits;

}

nDigit = (int)(lScratch & s_nBase64Mask[nNumBits]);

nNumBits = nBits;

if( nNumBits <=0 )

break;

strEncoded += s_strBase64TAB[ nDigit ];

}

// Rellenar con '=" según RFC 1521

while( strEncoded.GetLength() % 4 != 0 )

strEncoded += '=';

return strEncoded.GetLength();

}

/********************************************* ***** ****************************

*********** ******* ******************************************* ******** ******/

CHttpDownload::CHttpDownload():

m_hSocket(INVALID_SOCKET),

m_nResponseHeaderSize( 0)

{

memset(m_szRequestHeader, 0, sizeof(m_szRequestHeader));

memset(m_szResponseHeader, 0,

sizeof(m_szResponseHeader));

}

CHttpDownload::~CHttpDownload()

{

CloseSocket();

}

bool CHttpDownload::CreateSocket()

{

CloseSocket();

m_hSocket = socket(AF_INET , SOCK_STREAM, IPPROTO_TCP);

if (INVALID_SOCKET == m_hSocket)

{

devuelve falso;

}

devuelve verdadero;

}

void CHttpDownload::CloseSocket()

{

if (INVALID_SOCKET != m_hSocket )

{

closesocket(m_hSocket);

m_hSocket = INVALID_SOCKET;

}

}

void CHttpDownload::FormatRequestHeader(const char* pszServer, int nPort, const char* pszObject, const char *pAuthorization /* = NULL */)

{

memset (m_szRequestHeader, '\0', 1024);

//Línea 1: Método de solicitud, ruta, versión

strcat(m_szRequestHeader, "GET ");

strcat(m_szRequestHeader, pszObject);

strcat(m_szRequestHeader, " HTTP/1.0");

strcat(m_szRequestHeader, "\r\n");

//Línea 2: Tipo de datos solicitado

strcat(m_szRequestHeader, "Accept: */*");

strcat(m_szRequestHeader, "\r\ n");

//Línea 3: host, puerto

char szPort[10];

sprintf(szPort, ":%d", nPort);

strcat(m_szRequestHeader, "Host: ");

strcat(m_szRequestHeader, pszServer);

strcat(m_szRequestHeader, szPort);

p>

strcat(m_szRequestHeader, "\r\n");

//Línea 4: control de búfer

strcat(m_szRequestHeader, "Catch-control: no-cache");

strcat(m_szRequestHeader, "\r\n");

//Línea 5: Permisos de acceso

if (pAutorización)

{

CStri

ng strAuth;

strcat(m_szRequestHeader, "Autorización: Básica ");

CBase64::Base64Encode(pAuthorization, strAuth);

strcat(m_szRequestHeader, strAuth );

strcat(m_szRequestHeader, "\r\n");

}

//Última línea: línea en blanco

strcat(m_szRequestHeader, "\r\n");

}

bool CHttpDownload::SendRequest()

{

int len = strlen(m_szRequestHeader);

//if(send(m_hSocket,m_szRequestHeader,len,0)==SOCKET_ERROR)

//{

/ / return false;

//}

if (SelectSend(m_szRequestHeader, len ,DEFAULT_SENDTIMEOUT) <= 0)

{

devolver falso;

}

if (!GetResponseHeader())

{

devolver falso;

}

devuelve verdadero;

}

bool CHttpDownload::Connect(const char* pszHostIP, int nPort /* DEFAULT_PORT */, long ltimeout /* DEFAULT_CONNECTTIMEOUT */)

{

ASSERT(pszHostIP);

sockaddr_in addr;

memset( &addr, 0, sizeof(addr) );

addr.sin_family = AF_INET;

addr.sin_port = htons(nPort);

addr.sin_addr.S_un.S_addr = inet_addr(pszHostIP) ;

unsigned long ul = 1;

int ret = ioctlsocket(m_hSocket, FIONBIO, (unsigned long*)&ul);

if( ret == SOCKET_ERROR)

{

return false;

}

connect(m_hSocket, (sockaddr*)&addr, sizeof(addr)) ;

timeval timeout = { 1, ltimeout };

fd_set r

FD_ZERO(&r); &r);

ret = seleccionar(0, 0,

&r, 0, &timeout);

if( ret <= 0 )

{

return false;

}

// Generalmente, los sockets en modo sin bloqueo son difíciles de controlar. Puede considerar volver al modo de bloqueo según la situación real.

unsigned long ul1=

ret = ioctlsocket( m_hSocket, FIONBIO, (unsigned long*)&ul1);

if( ret == SOCKET_ERROR)

{

return false

}

devuelve verdadero;

}

bool CHttpDownload::GetResponseHeader()

{

char c = 0;

bool bEndResponse = false;

int nIndex = 0;

int ret;

while(!bEndResponse && nIndex < 1024)

{

ret = SelectRecv(&m_szResponseHeader[nIndex++], 1

if (ret <= 0);

devuelve falso;

if(nIndex >= 4)

{

if(m_szResponseHeader[nIndex - 4] == ' \r' && m_szResponseHeader [nIndex - 3] == '\n'

&& m_szResponseHeader[nIndex - 2] == '\r' && m_szResponseHeader[nIndex - 1] == '\n')

bEndResponse = true;

}

}

m_nResponseHeaderSize = nIndex;

devuelve verdadero;

}

int CHttpDownload::GetServerInfo(DWORD &dwContentLength, DWORD &dwStatusCode) const

{

if (0 == m_nResponseHeaderSize)

{

dwContentLength = -1

dwStatusCode = -1;

devuelve -1;

}

char szState[3];

szState[0] = m_szResponseHeader[9];

szState[1] = m_szResponseHeader[10];

szState[ 2] = m_s

zResponseHeader[11];

dwStatusCode = (DWORD)_ttol(szState);

// Obtener longitud del contenido

CString strResponseHeader = m_szResponseHeader;

int nPos = strResponseHeader.Find("Content-length:");

if (nPos == -1)

return -1;

CString strDownFileLen = strResponseHeader.Mid(nPos + strlen("Content-length:"));

nPos = strDownFileLen.Find("\r\n");

if ( nPos == -1)

return -1;

strDownFileLen = strDownFileLen.Left(nPos);

strDownFileLen.TrimLeft();

strDownFileLen.TrimRight();

// Longitud del contenido:

dwContentLength = (DWORD) _ttol( (LPCTSTR)strDownFileLen );

return 0;

}

int CHttpDownload::SelectSend(char *pData, int len, long timeout /* = DEFAULT_RECVTIMEOUT */)

{

fd_set writefds;

FD_ZERO(&writefds);

FD_SET(m_hSocket, &writefds);

timeval tv = { timeout, 0 }; /p>

int ret = select(0, NULL, &writefds, NULL, &tv);

if (ret == 0 || ret == SOCKET_ERROR)

{

devuelve 0;

}

if (FD_ISSET(m_hSocket, &writefds) == 0)

devuelve 0;

ret = enviar(m_hSocket, pData, len, 0);

if (ret == SOCKET_ERROR)

{

// DWORD dwError = WSAGetLastError();

devuelve 0;

}

si no (ret == 0)

{

devolver 0;

}

devolver ret;

}

int CHttpDownload::SelectRecv(char *pData, int len, tiempo de espera largo)

{

fd_set

readfds;

FD_ZERO(&readfds);

FD_SET(m_hSocket, &readfds);

timeval tv = { timeout, 0 }; > int ret = select(0, &readfds, NULL, NULL, &tv);

if (ret == 0 || ret == SOCKET_ERROR)

{

devuelve 0;

}

si (FD_ISSET(m_hSocket, &readfds) == 0)

devuelve 0;

ret = recv(m_hSocket, pData, len, 0);

if (ret == SOCKET_ERROR)

{

// DWORD dwError = WSAGetLastError();

devuelve 0;

}

si no (ret == 0)

{

devuelve 0 ;

}

devolver ret;

}

/*************** *** ************************************************* **** *******

Descargar archivos de registro de alarmas de eventos históricos

http://172.16.0.108/histevent.xml

* ************************************************* ***** *******************/

bool CHttpDownload::Download(LPCTSTR lpszDownloadUrl, LPCTSTR lpszSavePath)

{

int nPort;

CString strService, strObject;

if (!ParseURL(lpszDownloadUrl, strService, strObject, nPort))

{

devuelve falso;

}

if (!CreateSocket())

devuelve falso;

if (!Connect( strService, nPort))

devuelve falso;

FormatRequestHeader(strService, nPort, strObject);

if (!SendRequest( ))

return false;

DWORD dwFileLen, dwStatuCode;

if (-1 == GetServerInfo(dwFileLen, dwStatuCode))

{

>

return false;

}

CFile filedown;

if (!filedown.Open(lpszSavePath, CFile::modeCreate|CFile::modeWrite ))

{

return false;

}

DWORD dwTotalBytes = 0;

char szdata[ 2048] = { 0 };

while (dwTotalBytes < dwFileLen)

{

int nRecvBytes = SelectRecv(szdata, 2048

<); p> if (nRecvBytes <= 0 )

{

break;

}

filedown.Write(szdata, nRecvBytes);

dwTotalBytes += nRecvBytes;

}

CloseSocket();

filedown.Close();

if (dwTotalBytes < dwFileLen)

{

intentar

{

CFile::Remove(lpszSavePath);

}

captura (CFileException* e)

{

e->Delete();

}

devuelve falso;

}

devuelve verdadero;

}