yuyu2020
发表于 2020-12-10 16:47:53
{:5_90:}
liankling
发表于 2021-2-23 16:49:52
学会了
YGP.Escapist
发表于 2021-2-27 22:36:08
我写了一个socket类,recv返回两次第一次200OK第二次就Bad Request了有点迷惑阿
代码:
#pragma once
#include"EspString.hpp"
#pragma comment(lib,"ws2_32.lib")
#include<iostream>
class EspHttp
{
private:
unsigned int HSocket = INVALID_SOCKET;
bool IsPost = false;
bool IsHttps = false;
unsigned int ErrorCode;
unsigned short nPort;
EspString lpszScheme;//http or https
EspString lpszEntireURL;
EspString lpszHostName;//www.baidu.com
EspString lpszURLPath;// ...com/[.....]<-
EspString lpszProtocol;//Submitted/received protocol
EspString lpszAddInfo;//POST method
EspString lpszResult;//recv
EspString lpszStatus;//HTTP/1.1 200 OK HTTP/1.1 400 Bad Request
EspString lpszContent;// Manbody of the Result
bool RequestOK;//Whether is HTTP/1.1 200 OK
bool AnalyzeURL()
{
unsigned long ParsePos = 0; unsigned long TargetPos = 0;
assert(lpszEntireURL.GetBuffer() != NULL && ::IsBadStringPtrA(lpszEntireURL.GetBuffer(), -1) == false);
EspString lpszTempString;
TargetPos = lpszEntireURL.Find(":", 0);
if (TargetPos == -1)
return false;
lpszTempString = lpszEntireURL.GetLeftStr(TargetPos);
if (lpszTempString.CompareNoCase("http"))
lpszScheme = "http";
else if (lpszTempString.CompareNoCase("https"))
{
lpszScheme = "https";
IsHttps = true;
}
else
return false;
ParsePos += (lpszTempString.GetLength() + 3);
TargetPos = lpszEntireURL.Find(":", ParsePos);
if (TargetPos != -1)
{
lpszTempString = lpszEntireURL.GetMidStr(ParsePos, TargetPos - ParsePos);
if (lpszTempString.IsEmpty())return false;
lpszHostName = lpszTempString;
ParsePos += (lpszTempString.GetLength() + 1);
TargetPos = lpszEntireURL.Find("/", ParsePos);
if (TargetPos == -1)
return false;
nPort = ::strtoul(lpszEntireURL.GetMidStr(ParsePos, TargetPos - ParsePos).GetAnsiStr(), 0, 0);
}
else
{
TargetPos = lpszEntireURL.Find("/", ParsePos);
if (TargetPos == -1)
return false;
lpszTempString = lpszEntireURL.GetMidStr(ParsePos, TargetPos - ParsePos);
if (lpszTempString.IsEmpty())return false;
lpszHostName = lpszTempString;
if (IsHttps)
nPort = 443;
else
nPort = 80;
}
lpszURLPath = lpszEntireURL.GetMidStr(TargetPos, lpszEntireURL.GetLength() - TargetPos);
return true;
}
public:
EspHttp()
{
WSADATA SocketData = { 0 };
ErrorCode = ::WSAStartup(MAKEWORD(2, 2), &SocketData);
if (ErrorCode == 0)
{
HSocket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (HSocket == INVALID_SOCKET)
ErrorCode = ::WSAGetLastError();
}
}
~EspHttp()
{
if (ErrorCode == 0)
{
if (HSocket != INVALID_SOCKET)
::closesocket(HSocket);
::WSACleanup();
}
}
unsigned int GetLastError() { return ErrorCode; }
bool ConnectTo(const char* lpszURL, bool IsPOST = false, const char* lpszAddInfo = NULL)
{
assert(lpszURL != NULL && ::IsBadStringPtrA(lpszURL, -1) == false);
lpszEntireURL = lpszURL;
if (lpszEntireURL.IsEmpty())
return false;
if (!AnalyzeURL())
return false;
SOCKADDR_IN SocketAddr = { AF_INET,::htons(nPort),*((LPIN_ADDR) * ::gethostbyname(lpszHostName.GetAnsiStr())->h_addr_list) };
if (::connect(HSocket, (LPSOCKADDR)&SocketAddr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
ErrorCode = ::WSAGetLastError();
::closesocket(HSocket);
return false;
}
IsPost = IsPOST;
if (IsPost)
{
lpszProtocol.Append("POST ");
if (lpszAddInfo != NULL)
this->lpszAddInfo = lpszAddInfo;
}
else
lpszProtocol.Append("GET ");
lpszProtocol.Append(lpszURLPath.GetAnsiStr());
lpszProtocol.Append(" HTTP/1.1\r\n");
lpszProtocol.Append("Host: "); lpszProtocol.Append(lpszHostName.GetAnsiStr()); lpszProtocol.Append("\r\n");
}
void AddToProtocol(const char* lpszName, const char* lpszValue)
{
assert(lpszName != NULL && ::IsBadStringPtrA(lpszName, -1) == false);
assert(lpszValue != NULL && ::IsBadStringPtrA(lpszValue, -1) == false);
lpszProtocol.Append(lpszName);
lpszProtocol.Append(": ");
lpszProtocol.Append(lpszValue);
lpszProtocol.Append("\r\n");
}
bool SendRequest()
{
lpszProtocol.Append("\r\n");
if (IsPost)
lpszProtocol.Append(lpszAddInfo);
if (::send(HSocket, lpszProtocol.GetAnsiStr(), lpszProtocol.GetLength() + 1, 0) == SOCKET_ERROR)
{
ErrorCode = ::WSAGetLastError();
return false;
}
char* Buffer = (char*)::malloc(1025);
if (Buffer == NULL)
throw("Allocate Buffer Unsuccessfully");
unsigned long BufferSize = 0;
lpszResult.Empty();
do
{
BufferSize = ::recv(HSocket, Buffer, 1024, 0);
if (BufferSize > 0)
{
::memset(Buffer + BufferSize, 0, (1025 - BufferSize) * sizeof(char));
lpszResult.Append(Buffer);
}
else if (BufferSize == 0)
break;
else if (BufferSize == SOCKET_ERROR)
{
ErrorCode = ::WSAGetLastError();
return false;
}
} while (BufferSize != 0);
if (!lpszResult.IsEmpty())
{
unsigned long Pos1 = lpszResult.Find("\r\n");
if (Pos1 == -1)return false;
lpszStatus = lpszResult.GetLeftStr(Pos1);
unsigned long Pos2 = lpszResult.Find("\r\n\r\n");
if (Pos2 == -1)return false;
lpszProtocol = lpszResult.GetMidStr(Pos1, Pos2);
lpszContent = lpszResult.GetMidStr(Pos2+1, lpszResult.GetLength() - Pos2);
return true;
}
else
return false;
}
EspString GetResponce()
{
return lpszContent;
}
};
前前后后很多次了就是recv这个部分的问题其他部分没啥问题
goubaya
发表于 2021-4-2 00:53:02
谢谢,讲解
她与学业皆失
发表于 2021-4-12 19:12:48
表示看一遍根本没看懂
云陌风熏
发表于 2021-5-11 00:06:12
哈哈哈,涨芝士了{:10_257:}
li努力再努力
发表于 2021-5-24 15:44:57
收下了,重点
吕福轩
发表于 2021-6-6 22:51:12
DylanBee 发表于 2018-11-29 02:52
小甲鱼,您好,我是一名高中生,因为小时候喜欢计算机,所以瞎学了很多没用的知识,准确说不知道怎么去学, ...
怎么样了
corona_longyan
发表于 2021-6-21 11:48:11
总结一下,也许就一句话:
get和post本质上都是TCP链接,而get只产生一个数据包,post会产生两个数据包。
moskiller
发表于 2021-6-21 15:56:13
后退,我要开始在朋友前装逼了
56485668k
发表于 2021-10-19 15:28:13
沙发~
感谢楼主!
收下了。
3052524679
发表于 2021-11-17 19:14:58
看不懂咋办啊
2198425560
发表于 2022-1-11 17:52:00
细致啊
鱼cnb
发表于 2022-3-29 19:33:31
https://zhuanlan.zhihu.com/p/25028045
林乐耶
发表于 2022-11-29 10:46:47
逼格直接上去了,牛!
nick1095
发表于 2023-2-8 10:21:24
6,我现在就是大佬了{:10_257:}
Maybeking
发表于 2024-3-14 19:22:38
我要开始装逼了