Win C++ Socket模拟HTTP协议GET和POST,解决body内容不全,做了HTTP内容解析笔记

做完win socket后续修改实现Linux(jni,android)

萌新做笔记,请大佬勿喷,弟弟我屁话也不多,就不做详解了

QuickHttp.cpp核心

//
// Created by Administrator on 2022/7/31.
//

#include "QuickHttp.h"

int so;
string buf;

//WinSocket初始化
void QuickHttp::initWinSocket() {
   
    WSADATA wsaData;
    //参数:版本号,指向WSADATA结构体的指针
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    so = socket(AF_INET, SOCK_STREAM, 0);
}

string QuickHttp::getBuf() {
   
    return buf;
}

int QuickHttp::httpGet(const string &strUrl, const string &strMethod, const string &strData) {
   
    //绑定地址端口
    int iPort = getPortFromUrl(strUrl);
    if (iPort < 0) {
   
        debugOut("获取URL端口失败\n");
        return -1;
    }
    string strIP = getIpFromUrl(strUrl);
    if (strIP.empty()) {
   
        debugOut("从URL获取IP地址失败\n");
        return -1;
    }
    //创建HTTP协议表头
    string strHttpHead = httpHeadCreate(strMethod, strUrl, strData);

    SOCKADDR_IN in;  //服务端地址
    in.sin_port = htons(iPort);//连接端口6000
    //绑定目标ip
    if (inet_pton(AF_INET, strIP.data(), &in.sin_addr) <= 0) {
   
        debugOut("inet_pton error ! Error code: %d,Error message:%s\n", errno, strerror(errno));
        return -1;
    }
    in.sin_family = AF_INET;
    //连接到服务端
    int isRet = connect(so, (SOCKADDR *) &in, sizeof(SOCKADDR));
    if (isRet == -1) {
   
        return -1;
    }
    //非阻塞方式连接
    send(so, strHttpHead.data(), strlen(strHttpHead.data()) , 0);
    /**
     * how的方式有三种分别是
     * SHUT_RD(0):关闭sockfd上的读功能,此选项将不允许sockfd进行读操作。不允许接受。
     * SHUT_WR(1):关闭sockfd的写功能,此选项将不允许sockfd进行写操作。不允许发送。
     * SHUT_RDWR(2):关闭sockfd的读写功能。不允许发送和接受(和 close() 一样)。
     **/
    shutdown(so, 1);
    buf = httpDataTransmit(so);
    close(so);
    WSACleanup();
    return 1;
}

//发送HTTP请求并且接受响应
string QuickHttp::httpDataTransmit(int isSocFd) {
   
    //接受服务器返回的信息
    string info;//接受的信息
    char ch;//每次接受的信息
    int rlength = 0;//接受数据的总大小
    int rlen = recv(isSocFd, &ch, 1, 0);//每次接受的数据大小
    rlength += rlen;
    while (rlen != 0 && rlen != SOCKET_ERROR) {
   
        info += ch;
        rlen = recv(isSocFd, &ch, 1, 0);//每次接受的数据大小
        rlength += rlen;
    }

    //编码转换 防止在控制台显示乱码
    char *pszBuffer = new char[info.length() + 1];
    auto *pszWideBuffer = new wchar_t[(info.length() + 1) * 2];
    memset(pszWideBuffer, 0, (info.length() + 1) * 2);
    memset(pszBuffer, 0, info.length() + 1);
    int cchWideChar = info.length() + 1;
    MultiByteToWideChar(CP_UTF8, 0, info.c_str(), info.length(), pszWideBuffer, cchWideChar * 2);//将unicode编码,转换为宽字节
    WideCharToMultiByte(CP_ACP, 0, pszWideBuffer, wcslen(pszWideBuffer), pszBuffer, info

你可能感兴趣的:(c++,http,开发语言,websocket,网络协议)