- Joined
- Mar 19, 2009
- Messages
- 187
- Reaction score
- 0
- Trophies
- 1
- Location
- Paris
- Website
- Visit site
- XP
- 108
- Country

Hi everybody,
i've made a c++ class to encapsulate Http request mecanism. This class do its job without error when i compile it under Visual Studio and running under Windows.
But when i modify it to be compatible with wii (network initialization is different), it crash when the destructor is called (i think it's a segmentation fault, but i don't know where it can occure...).
Here is my code (download here)
NetworkRequest.h
CODE#ifndef _NETWORKREQUEST_H_
#define _NETWORKREQUEST_H_
#include
#include "NetworkResponse.h"
#include
#define NETWORK_BLOCK_SIZEÂÂÂÂ1000
#define NETWORK_PORTÂÂÂÂÂÂÂÂ80
class NetworkRequest
{
private:
ÂÂÂÂs32ÂÂ_sockfd;
ÂÂÂÂstd::string _request;
ÂÂÂÂstd::string _hostName;
ÂÂÂÂstd::string _path;
ÂÂÂÂvoid Connect();
ÂÂÂÂvoid Disconnect();
ÂÂÂÂstatic void Init();
ÂÂÂÂu32 Read(void *buffer, u32 len);
ÂÂÂÂvoid Write(const void *buffer, u32 len);
ÂÂÂÂu32 GetResponseLength();
public:
ÂÂÂÂNetworkRequest(const std::string &request);
ÂÂÂÂ~NetworkRequest();
ÂÂÂÂNetworkResponse GetResponse();
};
#endif
NetworkRequest.cpp
CODE#include "header/NetworkRequest.h"
#include
#include
#include
#include
#include
#include "header/Exception.h"
using namespace std;
void NetworkRequest::Init()
{
ÂÂÂÂstatic bool isInitialized = false;
ÂÂÂÂs32 ret;
ÂÂÂÂ/* if is already initialized, we do nothing */
ÂÂÂÂif(isInitialized)
ÂÂÂÂÂÂÂÂreturn;
ÂÂÂÂ/* Initialize network */
ÂÂÂÂstatic char _hostip[16];
ÂÂÂÂret = if_config(_hostip, NULL, NULL, true);
ÂÂÂÂif (ret < 0)
ÂÂÂÂÂÂÂÂthrow new Exception("Can't initialize network!",ret);
ÂÂÂÂisInitialized = true;
ÂÂÂÂreturn;
}
NetworkRequest::NetworkRequest(const string &request)
{
ÂÂÂÂ/* ensure that the network is initialized */
ÂÂÂÂInit();
ÂÂÂÂ/* store local variables */
ÂÂÂÂ_sockfd = -1;
ÂÂÂÂ_request = request;
ÂÂÂÂ_hostName = _request.substr(7,_request.find_first_of('/',7) - 7);
ÂÂÂÂ_path = request.substr(_hostName.size() + 7,string::npos);
}
void NetworkRequest::Connect()
{
ÂÂÂÂstruct hostent *he;
ÂÂÂÂstruct sockaddr_in sa;
ÂÂÂÂs32 ret;
ÂÂÂÂ/* Ensure that the socket is disconnected */
ÂÂÂÂDisconnect();
ÂÂÂÂ/* Create socket */
ÂÂÂÂ_sockfd = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
ÂÂÂÂif (_sockfd < 0)
ÂÂÂÂÂÂÂÂthrow new Exception("Error creating a socket!",_sockfd);
ÂÂÂÂ/* Get host by name */
ÂÂÂÂhe = net_gethostbyname(_hostName.c_str());
ÂÂÂÂif (!he)
ÂÂÂÂÂÂÂÂthrow new Exception("Can't find the host!",-1);
ÂÂÂÂ/* Setup socket */
ÂÂÂÂmemcpy(&sa.sin_addr, he->h_addr_list[0], he->h_length);
ÂÂÂÂsa.sin_family = AF_INET;
ÂÂÂÂsa.sin_port = htons(80);
ÂÂÂÂret = net_connect(_sockfd, (struct sockaddr *)&sa, sizeof(sa));
ÂÂÂÂif (ret < 0)
ÂÂÂÂÂÂÂÂthrow new Exception("Can't connect to the socket!",ret);
}
void NetworkRequest:
isconnect()
{
ÂÂÂÂif (_sockfd >= 0)
ÂÂÂÂ{
ÂÂÂÂÂÂÂÂnet_close(_sockfd);
ÂÂÂÂÂÂÂÂ_sockfd = -1;
ÂÂÂÂ}
}
NetworkRequest::~NetworkRequest()
{
ÂÂÂÂDisconnect();
}
u32 NetworkRequest::Read(void *buffer, u32 len)
{
ÂÂÂÂu32 read = 0, ret = 0;
ÂÂÂÂ/* Data to be read */
ÂÂÂÂfor (read = 0; read < len; read += ret) {
ÂÂÂÂÂÂÂÂu32 size;
ÂÂÂÂÂÂÂÂ/* Size to read */
ÂÂÂÂÂÂÂÂsize = len - read;
ÂÂÂÂÂÂÂÂif (size > NETWORK_BLOCK_SIZE)
ÂÂÂÂÂÂÂÂÂÂÂÂsize = NETWORK_BLOCK_SIZE;
ÂÂÂÂÂÂÂÂ/* Read network data */
ÂÂÂÂÂÂÂÂret = net_recv(_sockfd, (char*)buffer + read, size, 0);
ÂÂÂÂÂÂÂÂif (ret < 0)
ÂÂÂÂÂÂÂÂÂÂÂÂthrow new Exception("Can't read from the net socket!",ret);
ÂÂÂÂÂÂÂÂ/* Read finished */
ÂÂÂÂÂÂÂÂif (!ret)
ÂÂÂÂÂÂÂÂÂÂÂÂbreak;
ÂÂÂÂ}
ÂÂÂÂreturn read;
}
void NetworkRequest::Write(const void *buffer, u32 len)
{
ÂÂÂÂu32 ret = 0, written = 0;
ÂÂÂÂ/* Data to be written */
ÂÂÂÂfor (written = 0; written < len; written += ret) {
ÂÂÂÂÂÂÂÂu32 size;
ÂÂÂÂÂÂÂÂ/* Size to read */
ÂÂÂÂÂÂÂÂsize = len - written;
ÂÂÂÂÂÂÂÂif (size > NETWORK_BLOCK_SIZE)
ÂÂÂÂÂÂÂÂÂÂÂÂsize = NETWORK_BLOCK_SIZE;
ÂÂÂÂÂÂÂÂ/* Write network data */
ÂÂÂÂÂÂÂÂret = net_send(_sockfd, (char*)buffer + written, size, 0);
ÂÂÂÂÂÂÂÂif (ret < 0)
ÂÂÂÂÂÂÂÂÂÂÂÂthrow new Exception("Can't write into the net socket!",ret);
ÂÂÂÂÂÂÂÂ/* Write finished */
ÂÂÂÂÂÂÂÂif (!ret)
ÂÂÂÂÂÂÂÂÂÂÂÂbreak;
ÂÂÂÂ}
}
u32 NetworkRequest::GetResponseLength()
{
ÂÂÂÂchar buf[1024], *ptr = NULL;
ÂÂÂÂu32ÂÂlen;
ÂÂÂÂs32ÂÂret;
ÂÂÂÂstring totalRequest = "GET " + _path + " HTTP/1.1\r\nHost: " + _hostName + "\r\nConnection: close\r\n\r\n";
ÂÂÂÂ/* send request */
ÂÂÂÂret = net_send(_sockfd, totalRequest.c_str(), totalRequest.length(), 0);
ÂÂÂÂif(ret < 0)
ÂÂÂÂÂÂÂÂthrow new Exception("Impossible to send the request to the host!",ret);
ÂÂÂÂ/* Clear buffer */
ÂÂÂÂmemset(buf, 0, sizeof(buf));
ÂÂÂÂ/* Read HTTP header */
ÂÂÂÂfor (u32 cnt = 0; !strstr(buf, "\r\n\r\n"); cnt++)
ÂÂÂÂÂÂÂÂif (net_recv(_sockfd, buf + cnt, 1, 0) 0)
ÂÂÂÂ{
ÂÂÂÂÂÂÂÂ_buffer = (void*)new char[size];
ÂÂÂÂÂÂÂÂmemcpy(_buffer,buffer, size);
ÂÂÂÂ}
ÂÂÂÂelse
ÂÂÂÂÂÂÂÂ_buffer = NULL;
}
NetworkResponse::NetworkResponse(const NetworkResponse &src)
{
ÂÂÂÂ_size = src.Size();
ÂÂÂÂ_buffer = (void*)new char[_size];
ÂÂÂÂmemcpy(_buffer,src.Content(), _size);
}
NetworkResponse& NetworkResponse::operator=(const NetworkResponse &src)
{
ÂÂÂÂif(_buffer != NULL)
ÂÂÂÂ{
ÂÂÂÂÂÂÂÂdelete[] (char*)_buffer;
ÂÂÂÂÂÂÂÂ_buffer = NULL;
ÂÂÂÂ}
ÂÂÂÂ_buffer = (void*)new char[src.Size()];
ÂÂÂÂmemcpy(_buffer,src.Content(), src.Size());
ÂÂÂÂ_size = src.Size();
ÂÂÂÂreturn *this;
}
NetworkResponse::~NetworkResponse()
{
ÂÂÂÂif(_buffer != NULL)
ÂÂÂÂ{
ÂÂÂÂÂÂÂÂdelete[] (char*)_buffer;
ÂÂÂÂÂÂÂÂ_buffer = NULL;
ÂÂÂÂ}
}
u64 NetworkResponse::Size() const
{
ÂÂÂÂreturn _size;
}
void* NetworkResponse::Content() const
{
ÂÂÂÂreturn _buffer;
}
i've made a c++ class to encapsulate Http request mecanism. This class do its job without error when i compile it under Visual Studio and running under Windows.
But when i modify it to be compatible with wii (network initialization is different), it crash when the destructor is called (i think it's a segmentation fault, but i don't know where it can occure...).
Here is my code (download here)
NetworkRequest.h
CODE#ifndef _NETWORKREQUEST_H_
#define _NETWORKREQUEST_H_
#include
#include "NetworkResponse.h"
#include
#define NETWORK_BLOCK_SIZEÂÂÂÂ1000
#define NETWORK_PORTÂÂÂÂÂÂÂÂ80
class NetworkRequest
{
private:
ÂÂÂÂs32ÂÂ_sockfd;
ÂÂÂÂstd::string _request;
ÂÂÂÂstd::string _hostName;
ÂÂÂÂstd::string _path;
ÂÂÂÂvoid Connect();
ÂÂÂÂvoid Disconnect();
ÂÂÂÂstatic void Init();
ÂÂÂÂu32 Read(void *buffer, u32 len);
ÂÂÂÂvoid Write(const void *buffer, u32 len);
ÂÂÂÂu32 GetResponseLength();
public:
ÂÂÂÂNetworkRequest(const std::string &request);
ÂÂÂÂ~NetworkRequest();
ÂÂÂÂNetworkResponse GetResponse();
};
#endif
NetworkRequest.cpp
CODE#include "header/NetworkRequest.h"
#include
#include
#include
#include
#include
#include "header/Exception.h"
using namespace std;
void NetworkRequest::Init()
{
ÂÂÂÂstatic bool isInitialized = false;
ÂÂÂÂs32 ret;
ÂÂÂÂ/* if is already initialized, we do nothing */
ÂÂÂÂif(isInitialized)
ÂÂÂÂÂÂÂÂreturn;
ÂÂÂÂ/* Initialize network */
ÂÂÂÂstatic char _hostip[16];
ÂÂÂÂret = if_config(_hostip, NULL, NULL, true);
ÂÂÂÂif (ret < 0)
ÂÂÂÂÂÂÂÂthrow new Exception("Can't initialize network!",ret);
ÂÂÂÂisInitialized = true;
ÂÂÂÂreturn;
}
NetworkRequest::NetworkRequest(const string &request)
{
ÂÂÂÂ/* ensure that the network is initialized */
ÂÂÂÂInit();
ÂÂÂÂ/* store local variables */
ÂÂÂÂ_sockfd = -1;
ÂÂÂÂ_request = request;
ÂÂÂÂ_hostName = _request.substr(7,_request.find_first_of('/',7) - 7);
ÂÂÂÂ_path = request.substr(_hostName.size() + 7,string::npos);
}
void NetworkRequest::Connect()
{
ÂÂÂÂstruct hostent *he;
ÂÂÂÂstruct sockaddr_in sa;
ÂÂÂÂs32 ret;
ÂÂÂÂ/* Ensure that the socket is disconnected */
ÂÂÂÂDisconnect();
ÂÂÂÂ/* Create socket */
ÂÂÂÂ_sockfd = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
ÂÂÂÂif (_sockfd < 0)
ÂÂÂÂÂÂÂÂthrow new Exception("Error creating a socket!",_sockfd);
ÂÂÂÂ/* Get host by name */
ÂÂÂÂhe = net_gethostbyname(_hostName.c_str());
ÂÂÂÂif (!he)
ÂÂÂÂÂÂÂÂthrow new Exception("Can't find the host!",-1);
ÂÂÂÂ/* Setup socket */
ÂÂÂÂmemcpy(&sa.sin_addr, he->h_addr_list[0], he->h_length);
ÂÂÂÂsa.sin_family = AF_INET;
ÂÂÂÂsa.sin_port = htons(80);
ÂÂÂÂret = net_connect(_sockfd, (struct sockaddr *)&sa, sizeof(sa));
ÂÂÂÂif (ret < 0)
ÂÂÂÂÂÂÂÂthrow new Exception("Can't connect to the socket!",ret);
}
void NetworkRequest:
{
ÂÂÂÂif (_sockfd >= 0)
ÂÂÂÂ{
ÂÂÂÂÂÂÂÂnet_close(_sockfd);
ÂÂÂÂÂÂÂÂ_sockfd = -1;
ÂÂÂÂ}
}
NetworkRequest::~NetworkRequest()
{
ÂÂÂÂDisconnect();
}
u32 NetworkRequest::Read(void *buffer, u32 len)
{
ÂÂÂÂu32 read = 0, ret = 0;
ÂÂÂÂ/* Data to be read */
ÂÂÂÂfor (read = 0; read < len; read += ret) {
ÂÂÂÂÂÂÂÂu32 size;
ÂÂÂÂÂÂÂÂ/* Size to read */
ÂÂÂÂÂÂÂÂsize = len - read;
ÂÂÂÂÂÂÂÂif (size > NETWORK_BLOCK_SIZE)
ÂÂÂÂÂÂÂÂÂÂÂÂsize = NETWORK_BLOCK_SIZE;
ÂÂÂÂÂÂÂÂ/* Read network data */
ÂÂÂÂÂÂÂÂret = net_recv(_sockfd, (char*)buffer + read, size, 0);
ÂÂÂÂÂÂÂÂif (ret < 0)
ÂÂÂÂÂÂÂÂÂÂÂÂthrow new Exception("Can't read from the net socket!",ret);
ÂÂÂÂÂÂÂÂ/* Read finished */
ÂÂÂÂÂÂÂÂif (!ret)
ÂÂÂÂÂÂÂÂÂÂÂÂbreak;
ÂÂÂÂ}
ÂÂÂÂreturn read;
}
void NetworkRequest::Write(const void *buffer, u32 len)
{
ÂÂÂÂu32 ret = 0, written = 0;
ÂÂÂÂ/* Data to be written */
ÂÂÂÂfor (written = 0; written < len; written += ret) {
ÂÂÂÂÂÂÂÂu32 size;
ÂÂÂÂÂÂÂÂ/* Size to read */
ÂÂÂÂÂÂÂÂsize = len - written;
ÂÂÂÂÂÂÂÂif (size > NETWORK_BLOCK_SIZE)
ÂÂÂÂÂÂÂÂÂÂÂÂsize = NETWORK_BLOCK_SIZE;
ÂÂÂÂÂÂÂÂ/* Write network data */
ÂÂÂÂÂÂÂÂret = net_send(_sockfd, (char*)buffer + written, size, 0);
ÂÂÂÂÂÂÂÂif (ret < 0)
ÂÂÂÂÂÂÂÂÂÂÂÂthrow new Exception("Can't write into the net socket!",ret);
ÂÂÂÂÂÂÂÂ/* Write finished */
ÂÂÂÂÂÂÂÂif (!ret)
ÂÂÂÂÂÂÂÂÂÂÂÂbreak;
ÂÂÂÂ}
}
u32 NetworkRequest::GetResponseLength()
{
ÂÂÂÂchar buf[1024], *ptr = NULL;
ÂÂÂÂu32ÂÂlen;
ÂÂÂÂs32ÂÂret;
ÂÂÂÂstring totalRequest = "GET " + _path + " HTTP/1.1\r\nHost: " + _hostName + "\r\nConnection: close\r\n\r\n";
ÂÂÂÂ/* send request */
ÂÂÂÂret = net_send(_sockfd, totalRequest.c_str(), totalRequest.length(), 0);
ÂÂÂÂif(ret < 0)
ÂÂÂÂÂÂÂÂthrow new Exception("Impossible to send the request to the host!",ret);
ÂÂÂÂ/* Clear buffer */
ÂÂÂÂmemset(buf, 0, sizeof(buf));
ÂÂÂÂ/* Read HTTP header */
ÂÂÂÂfor (u32 cnt = 0; !strstr(buf, "\r\n\r\n"); cnt++)
ÂÂÂÂÂÂÂÂif (net_recv(_sockfd, buf + cnt, 1, 0) 0)
ÂÂÂÂ{
ÂÂÂÂÂÂÂÂ_buffer = (void*)new char[size];
ÂÂÂÂÂÂÂÂmemcpy(_buffer,buffer, size);
ÂÂÂÂ}
ÂÂÂÂelse
ÂÂÂÂÂÂÂÂ_buffer = NULL;
}
NetworkResponse::NetworkResponse(const NetworkResponse &src)
{
ÂÂÂÂ_size = src.Size();
ÂÂÂÂ_buffer = (void*)new char[_size];
ÂÂÂÂmemcpy(_buffer,src.Content(), _size);
}
NetworkResponse& NetworkResponse::operator=(const NetworkResponse &src)
{
ÂÂÂÂif(_buffer != NULL)
ÂÂÂÂ{
ÂÂÂÂÂÂÂÂdelete[] (char*)_buffer;
ÂÂÂÂÂÂÂÂ_buffer = NULL;
ÂÂÂÂ}
ÂÂÂÂ_buffer = (void*)new char[src.Size()];
ÂÂÂÂmemcpy(_buffer,src.Content(), src.Size());
ÂÂÂÂ_size = src.Size();
ÂÂÂÂreturn *this;
}
NetworkResponse::~NetworkResponse()
{
ÂÂÂÂif(_buffer != NULL)
ÂÂÂÂ{
ÂÂÂÂÂÂÂÂdelete[] (char*)_buffer;
ÂÂÂÂÂÂÂÂ_buffer = NULL;
ÂÂÂÂ}
}
u64 NetworkResponse::Size() const
{
ÂÂÂÂreturn _size;
}
void* NetworkResponse::Content() const
{
ÂÂÂÂreturn _buffer;
}








