BCB6中socket http通信

top_endless 2011-02-24 04:11:43
之前学习了用IDHTTP和ClientSocket来向网站发送请求获得指定网页的源代码,现在只想使用socket实现,不使用sendText()
和ReceiveText()方法,也就是纯代码方法实现,请高手提供思路和实现代码。
...全文
209 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
top_endless 2011-02-26
  • 打赏
  • 举报
回复
感谢大家的回答,结合你们的回答我思考思考。。
CppFile 2011-02-24
  • 打赏
  • 举报
回复



// ******************************************************************************************************* // SendRequest // //*******************************************************************************************************
int Request::SendRequest(bool IsPost, string url, string& psHeaderSend, string& psHeaderReceive, string& psMessage)
{
HTTPRequest req;
int i, rtn;
LPSTR buffer;
req.headerSend = NULL;
req.headerReceive = NULL;
req.message = NULL; // Read in arguments
if (IsPost)
{
/* POST */ i = psHeaderSend.length();
buffer = (char*)malloc(i + 1);
strcpy(buffer, psHeaderSend.c_str());
rtn = SendHTTP(url, "Content-Type: application/x-www-form-urlencoded\r\n", (unsigned char*)buffer, i, &req);
free(buffer);
}
else
/* GET */ {
rtn = SendHTTP(url, NULL, NULL, 0, &req);
}
if (!rtn) // Output message and/or headerSend
{
psHeaderSend = req.headerSend;
psHeaderReceive = req.headerReceive;
psMessage = req.message;
free(req.headerSend);
free(req.headerReceive);
free(req.message);
return 1;
}
else
{
return 0;
}
}

int Request::httpgzdecompress(BYTE *zdata, unsigned long nzdata, BYTE *data, unsigned long *ndata)
{
int err = 0;
z_stream d_stream = {0}; /* decompression stream */
static char dummy_head[2] =
{
0x8 + 0x7 * 0x10,
(((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
};
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = zdata;
d_stream.avail_in = 0;
d_stream.next_out = data;
if(inflateInit2(&d_stream, 47) != Z_OK) return -1;
while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
if(err != Z_OK )
{
if(err == Z_DATA_ERROR)
{
d_stream.next_in = (Bytef*) dummy_head;
d_stream.avail_in = sizeof(dummy_head);
if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK)
{
return -1;
}
}
else return -1;
}
}
if(inflateEnd(&d_stream) != Z_OK) return -1;
*ndata = d_stream.total_out;
return 0;
}


这里有个bug,网站传回来的数据,可能经过gzip压缩,这样压缩的结果就可能不是字符串形式,这样直接将数据用char *来转化是不行的,我还没改过来,不过实现了用gzip解压。

这个代码有问题,只给你提供一个思路
CppFile 2011-02-24
  • 打赏
  • 举报
回复
.cpp
[code=C/C++]
// ---------------------------------------------------------------------------

#pragma hdrstop

#include "Request.h"
#include <vcl.h>
#include "zlib.h"

// ---------------------------------------------------------------------------

#pragma package(smart_init)

Request::Request()
{ tmp=new unsigned char[1024*100];

}

Request::~Request()
{
if(tmp) delete []tmp;
}

// ******************************************************************************************************* //MemBufferCreate: // Passed a MemBuffer structure, will allocate a memory buffer // of MEM_BUFFER_SIZE. This buffer can then grow as needed. //*******************************************************************************************************
void Request::MemBufferCreate(MemBuffer *b)
{
b->size = MEM_BUFFER_SIZE;
b->buffer = (unsigned char*)malloc(b->size);
b->position = b->buffer;
}

// ******************************************************************************************************* // MemBufferGrow: // Double the size of the buffer that was passed to this function. //*******************************************************************************************************
void Request::MemBufferGrow(MemBuffer *b)
{
size_t sz;
sz = b->position - b->buffer;
b->size = b->size * 2;
b->buffer = (unsigned char*)realloc(b->buffer, b->size);
b->position = b->buffer + sz;

// readjust current position
}
// *******************************************************************************************************
// MemBufferAddByte:
// Add a single byte to the memory buffer, grow if needed.
// ****************************************************
void Request::MemBufferAddByte(MemBuffer *b, unsigned char byt)
{
if ((size_t)(b->position - b->buffer) >= b->size)
MemBufferGrow(b);
*(b->position++) = byt;
}

// ******************************************************************************************************* // MemBufferAddBuffer: // Add a range of bytes to the memory buffer, grow if needed. //*******************************************************************************************************
void Request::MemBufferAddBuffer(MemBuffer *b, unsigned char *buffer, size_t size)
{
while (((size_t)(b->position - b->buffer) + size) >= b->size)
MemBufferGrow(b);
memcpy(b->position, buffer, size);
b->position += size;
}

// ******************************************************************************************************* // GetHostAddress: // Resolve using DNS or similar(WINS,etc) the IP // address for a domain name such as www.wdj.com. //*******************************************************************************************************
DWORD Request::GetHostAddress(LPCSTR host)
{
struct hostent *phe;
char *p;
phe = gethostbyname(host);
if (phe == NULL)
return 0;
p = *phe->h_addr_list;
return *((DWORD*)p);
}

// ******************************************************************************************************* // SendString: // Send a string(null terminated) over the specified socket. //*******************************************************************************************************
void Request::SendString(SOCKET sock, LPCSTR str)
{
send(sock, str, strlen(str), 0);
}

// ******************************************************************************************************* // ValidHostChar: // Return TRUE if the specified character is valid // for a host name, i.e. A-Z or 0-9 or -.: //*******************************************************************************************************
BOOL Request::ValidHostChar(char ch)
{
return(isalpha(ch) || isdigit(ch) || ch == '-' || ch == '.' || ch == ':');
} // ******************************************************************************************************* // ParseURL: // Used to break apart a URL such as // http://www.localhost.com:80/TestPost.htm into protocol, port, host and request. //******************

void Request::ParseURL(string url, LPSTR protocol, int lprotocol, LPSTR host, int lhost, LPSTR request, int lrequest, int *port)
{
char *work, *ptr, *ptr2;
*protocol = *host = *request = 0;
*port = 80;
work = strdup(url.c_str());
strupr(work);
ptr = strchr(work, ':');
// find protocol if any
if (ptr != NULL)
{
*(ptr++) = 0;
lstrcpyn(protocol, work, lprotocol);
}
else
{
lstrcpyn(protocol, "HTTP", lprotocol);
ptr = work;
}
if ((*ptr == '/') && (*(ptr + 1) == '/')) // skip past opening /'s
ptr += 2;
ptr2 = ptr; // find host
while (ValidHostChar(*ptr2) && *ptr2)
ptr2++;
*ptr2 = 0;
lstrcpyn(host, ptr, lhost);
lstrcpyn(request, url.c_str() + (ptr2 - work), lrequest); // find the request
ptr = strchr(host, ':'); // find the port number, if any
if (ptr != NULL)
{
*ptr = 0;
*port = atoi(ptr + 1);
}
free(work);
}

int Request::SendHTTP(string url, LPCSTR headerReceive, BYTE *post, DWORD postLength, HTTPRequest *req)
{
WSADATA WsaData;
SOCKADDR_IN sin;
SOCKET sock;
char buffer[512];
char protocol[20], host[256], request[1024];
int l, port, chars, err;
MemBuffer headersBuffer, messageBuffer;
char headerSend[1024];
BOOL done;
ParseURL(url, protocol, sizeof(protocol), host, sizeof(host), // Parse the URL
request, sizeof(request), &port);
if (strcmp(protocol, "HTTP"))
return 1;
err = WSAStartup(0x0101, &WsaData); // Init Winsock
if (err != 0)
return 1;
sock = socket(AF_INET, SOCK_STREAM, 0); // if (socket == INVALID_SOCKET)
if (sock == INVALID_SOCKET)
{
return 1;
}
sin.sin_family = AF_INET; // Connect to web sever
sin.sin_port = htons((unsigned short)port);
sin.sin_addr.s_addr = GetHostAddress(host);
if (connect(sock, (LPSOCKADDR) & sin, sizeof(SOCKADDR_IN)))
{
return 1;
}
if (!*request)
lstrcpyn(request, "/", sizeof(request));
if (post == NULL)
{
SendString(sock, "GET ");
strcpy(headerSend, "GET ");
}
else
{
SendString(sock, "POST ");
strcpy(headerSend, "POST ");
}
SendString(sock, request);
strcat(headerSend, request);
SendString(sock, " HTTP/1.0\r\n");
strcat(headerSend, " HTTP/1.0\r\n");
SendString(sock, "Accept: image/gif, image/x-xbitmap," " image/jpeg, image/pjpeg, application/vnd.ms-excel," " application/msword, application/vnd.ms-powerpoint," " */*\r\n");
strcat(headerSend, "Accept: image/gif, image/x-xbitmap," " image/jpeg, image/pjpeg, application/vnd.ms-excel," " application/msword, application/vnd.ms-powerpoint," " */*\r\n");
SendString(sock, "Accept-Language: en-us\r\n");
strcat(headerSend, "Accept-Language: en-us\r\n");
SendString(sock, "Accept-Encoding: gzip, default\r\n");
strcat(headerSend, "Accept-Encoding: gzip, default\r\n");
// SendString(sock, "Accept-Encoding: default\r\n");
// strcat(headerSend, "Accept-Encoding: default\r\n");
SendString(sock, "User-Agent: Neeao/4.0\r\n");
strcat(headerSend, "User-Agent: Neeao/4.0\r\n");
if (postLength)
{
sprintf(buffer, "Content-Length: %ld\r\n", postLength);
SendString(sock, buffer);
strcat(headerSend, buffer);
}
SendString(sock, "Host: ");
strcat(headerSend, "Host: ");
SendString(sock, host);
strcat(headerSend, host);
SendString(sock, "\r\n");
strcat(headerSend, "\r\n");
if ((headerReceive != NULL) && *headerReceive)
{
SendString(sock, headerReceive);
strcat(headerSend, headerReceive);
}
SendString(sock, "\r\n"); // Send a blank line to signal end of HTTP headerReceive
strcat(headerSend, "\r\n");
if ((post != NULL) && postLength)
{
send(sock, (const char*)post, postLength, 0);
post[postLength] = '\0';
strcat(headerSend, (const char*)post);
}
req->headerSend = (char*)malloc(sizeof(char*) * strlen(headerSend));
strcpy(req->headerSend, (char*)headerSend);
MemBufferCreate(&headersBuffer);
chars = 0;
done = FALSE;
while (!done)
{
l = recv(sock, buffer, 1, 0);
if (l < 0)
done = TRUE;
switch(*buffer)
{
case '\r':
break;
case '\n':
if (chars == 0)
done = TRUE;
chars = 0;
break;
default:
chars++;
break;
}
MemBufferAddByte(&headersBuffer, *buffer);
}
req->headerReceive = (char*)headersBuffer.buffer;
*(headersBuffer.position) = 0;
MemBufferCreate(&messageBuffer); // Now read the HTTP body
TLog &log=TLog::Instance();
do
{
l = recv(sock, buffer, sizeof(buffer) - 1, 0);
if (l < 0)
break;
*(buffer + l) = 0;
// log.LogBin(buffer,l);
MemBufferAddBuffer(&messageBuffer, (unsigned char*) & buffer, l);
}
while (l > 0);
*messageBuffer.position = 0;
//判断是否压缩过
if(strstr(req->headerReceive,"gzip"))
{
//压缩过
// gzdecompress(BYTE *zdata, unsigned long nzdata, BYTE *data, unsigned long *ndata)
httpgzdecompress(messageBuffer.buffer,messageBuffer.position - messageBuffer.buffer,tmp,&tmp_len);
tmp[tmp_len]=0;
req->message = (char*)tmp;
req->messageLength = tmp_len;
}
else
{
req->message = (char*)messageBuffer.buffer;
req->messageLength = (messageBuffer.position - messageBuffer.buffer);
}
closesocket(sock); // Cleanup
return 0;
}
CppFile 2011-02-24
  • 打赏
  • 举报
回复
给你个代码参考下, 我也是从网上找出的
.h

// ---------------------------------------------------------------------------

#ifndef RequestH
#define RequestH
// ---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <winsock2.h>
#pragma comment(lib, "WS2_32.lib")
using namespace std;
#define MEM_BUFFER_SIZE 10
/* HTTPRequest: Structure that returns the HTTP headers and message from the request */
typedef struct
{
LPSTR headerSend; // Pointer to HTTP header Send
LPSTR headerReceive; // Pointer to HTTP headers Receive
LPSTR message; // Pointer to the HTTP message
long messageLength; // Length of the message
}HTTPRequest; /* MemBuffer: Structure used to implement a memory buffer, which is a buffer of memory that will grow to hold variable sized parts of the HTTP message. */
typedef struct
{
unsigned char *buffer;
unsigned char *position;
size_t size;
}MemBuffer;

class Request
{
public:
Request();
virtual ~Request();

private:
void MemBufferCreate(MemBuffer *b);
void MemBufferGrow(MemBuffer *b);
void MemBufferAddByte(MemBuffer *b, unsigned char byt);
void MemBufferAddBuffer(MemBuffer *b, unsigned char *buffer, size_t size);
DWORD GetHostAddress(LPCSTR host);
void SendString(SOCKET sock, LPCSTR str);
BOOL ValidHostChar(char ch);
void ParseURL(string url, LPSTR protocol, int lprotocol, LPSTR host, int lhost, LPSTR request, int lrequest, int *port);
int SendHTTP(string url, LPCSTR headerReceive, BYTE *post, DWORD postLength, HTTPRequest *req);
int Request::httpgzdecompress(BYTE *zdata, unsigned long nzdata, BYTE *data, unsigned long *ndata);
unsigned char *tmp;
unsigned long tmp_len;

public:
int SendRequest(bool IsPost, string url, string& psHeaderSend, string& pszHeaderReceive, string& pszMessage);
};
#endif

top_endless 2011-02-24
  • 打赏
  • 举报
回复
up!高手来造福菜鸟啊~~~
fall513 2011-02-24
  • 打赏
  • 举报
回复
帮你顶下
顺便表示关注

13,874

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧