C++ 实现 ping 功能&& 域名(URL)解析实际 IP地址

C++ HTTP客户端实战:libcurl与cpp-httplib选型、集成与性能优化指南 HTTP协议作为现代网络通信的基石,其客户端实现是应用程序与Web服务交互的核心技术。在C++工程实践中,选择合适的HTTP客户端库并正确集成,是保障网络功能稳定与高效的关键。libcurl作为功能全面的行业标准,提供了强大的协议支持和精细的控制能力,尤其适合企业级应用和复杂网络环境。而cpp-httplib以其零依赖、单头文件的极简设计,显著降低了集成复杂度,非常适合快速原型开发和资源受限场景。理解两者的核心差异与适用场景,能帮助开发者根据项目需求做出最优选型。本文通过对比分析、实战代码示例及性能优化建议 阅读详情

1、简述

一般情况下,我们想知道在当前电脑设备环境下,某一个网址能不能访问,最简单的方法是win + R 键 ,输入cmd,召唤cmd命令行程序,然后直接用ping命令 + 网址 来看返回的结果,那么我们是通过windows提供的工具来得到相应的结果,那我们能不能自己用代码实现呢?
答案肯定是可以的,在我们输入ping命令后,cmd.exe解析后就进行相应的操作,而我们就是去实现这个操作,下面就讲述一下如何用代码实现。

2、代码之路

我们先来看看用windows提供的cmd命令行程序通过ping命令得到的结果。
这里我们 ping 了 百度的网址,下图为 ping 了 两次得到的结果,我们发现返回来的实际IP地址不一样,这里也很容易理解,因为我们在浏览器访问一个网址,是经过DNS域名解析服务器根据主机名解析得到对应的IP地址,而百度在各个地方有多台服务器,所以这里返回的IP并不止一个。(这里简单提一下,详细请百度一下O(∩_∩)O)

这里写图片描述

我们可以直接ping + 域名(也就是网址) , 也可以 ping + IP(这里也就是域名对应的实际IP地址),我们看到,通过ping www.baidu.com ,我们可以看到实际的IP地址,这里我们也可以直接ping + IP得到返回结果。

这里写图片描述


我们也看到了通过ping可以得到域名对应的实际IP地址,那我们也可以通过代码来实现,并且能够返回域名对应的全部IP地址。

域名解析实际IP地址

BOOL  GetRealIpByDomainName(char *szHost, char szIp[50][100], int *nCount)
{
    WSADATA wsaData;
    HOSTENT *pHostEnt;
    int nAdapter = 0;
    struct sockaddr_in   sAddr;
    if (WSAStartup(0x0101, &wsaData))
    {
        printf(" gethostbyname error for host:\n");
        return FALSE;
    }

    pHostEnt = gethostbyname(szHost);
    if (pHostEnt)
    {
        while (pHostEnt->h_addr_list[nAdapter])
        {
            memcpy(&sAddr.sin_addr.s_addr, pHostEnt->h_addr_list[nAdapter], pHostEnt->h_length);

            sprintf_s(szIp[nAdapter], "%s", inet_ntoa(sAddr.sin_addr));

            nAdapter++;
        }

        *nCount = nAdapter;
    }
    else
    {
        DWORD  dwError = GetLastError();
        *nCount = 0;
    }
    WSACleanup();
    return TRUE;
}
//测试代码
void main()
{
    // 返回的域名对应实际IP的个数
    int nIpCount = 0;
    // 返回的域名对应实际I列表
    char szIpList[50][100];
    // 域名
    char szDomain[256] = { 0 };
    char szIp[1024] = { 0 };
    strcpy_s(szDomain, "www.baidu.com");
    GetIpByDomainName(szDomain, szIpList, &nIpCount);

    for (int i = 0; i < nIpCount; i++)
    {
        strcat_s(szIp, szIpList[i]);
        strcat_s(szIp, "\t");
    }
    printf("DomainName : %s \n", szDomain);
    printf("Real IPList : %s", szIp);
}

测试结果

这里写图片描述

可以看出结果与用cmd命令行程序得到的结果一致。
这里 www.baidu.com 对应两个IP。这里是我这个地区得到的IP,其他地区以cmd命令行程序 ping的结果为准。ping的前提下是本地没有配置host文件,可以在 C:\Windows\System32\drivers\etc\hosts 这个文件中查看是否将某些域名配置成了固定的IP地址。

hosts简介

hosts文件其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交DNS域名解析服务器进行IP地址的解析。

hosts小应用

hosts文件就相当于本地网址的第一层过滤,可以把一些不想访问的网址进行过滤(比如恶意弹出的广告和网页游戏等),达到一层保护的效果
比如在hosts文件中添加 www.baidu.com 127.0.0.1 , 这样我们就访问不了百度网址了。

前几天也在某一篇文章中看到通过修改hosts文件配置可以过滤播放器的一些视频广告,具体做法详情百度一下哈 (^o^)/~。


C++ 实现 ping 功能

以下代码实现了我们的 cmd命令行程序中的ping 功能,但是只能够ping + IP 地址,不能够进行ping + 域名 ,需要配合上面的代码进行使用。

parseurl.h

#pragma once

#include <winsock2.h> 
#include<stdlib.h>

#pragma comment(lib, "Ws2_32.lib")

#define DEF_PACKET_SIZE 32
#define ECHO_REQUEST 8
#define ECHO_REPLY 0

struct IPHeader
{
    BYTE m_byVerHLen; //4位版本+4位首部长度
    BYTE m_byTOS; //服务类型
    USHORT m_usTotalLen; //总长度
    USHORT m_usID; //标识
    USHORT m_usFlagFragOffset; //3位标志+13位片偏移
    BYTE m_byTTL; //TTL
    BYTE m_byProtocol; //协议
    USHORT m_usHChecksum; //首部检验和
    ULONG m_ulSrcIP; //源IP地址
    ULONG m_ulDestIP; //目的IP地址
};

struct ICMPHeader
{
    BYTE m_byType; //类型
    BYTE m_byCode; //代码
    USHORT m_usChecksum; //检验和 
    USHORT m_usID; //标识符
    USHORT m_usSeq; //序号
    ULONG m_ulTimeStamp; //时间戳(非标准ICMP头部)
};

struct PingReply
{
    USHORT m_usSeq;
    DWORD m_dwRoundTripTime;
    DWORD m_dwBytes;
    DWORD m_dwTTL;
};

class ParseUrl
{
public:
    ParseUrl();
    ~ParseUrl();
    BOOL Ping(DWORD dwDestIP, PingReply *pPingReply = NULL, DWORD dwTimeout = 2000);
    BOOL Ping(char *szDestIP, PingReply *pPingReply = NULL, DWORD dwTimeout = 2000);
private:
    BOOL PingCore(DWORD dwDestIP, PingReply *pPingReply, DWORD dwTimeout);
    USHORT CalCheckSum(USHORT *pBuffer, int nSize);
    ULONG GetTickCountCalibrate();
private:
    SOCKET m_sockRaw;
    WSAEVENT m_event;
    USHORT m_usCurrentProcID;
    char *m_szICMPData;
    BOOL m_bIsInitSucc;
private:
    static USHORT s_usPacketSeq;
};

parseurl.cpp

#include "stdafx.h"
#include "parseurl.h"

USHORT ParseUrl::s_usPacketSeq = 0;

ParseUrl::ParseUrl() :
m_szICMPData(NULL),
m_bIsInitSucc(FALSE)
{
    WSADATA WSAData;
    WSAStartup(MAKEWORD(1, 1), &WSAData);

    m_event = WSACreateEvent();
    m_usCurrentProcID = (USHORT)GetCurrentProcessId();

    if ((m_sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0)) != SOCKET_ERROR)
    {
        WSAEventSelect(m_sockRaw, m_event, FD_READ);
        m_bIsInitSucc = TRUE;

        m_szICMPData = (char*)malloc(DEF_PACKET_SIZE + sizeof(ICMPHeader));

        if (m_szICMPData == NULL)
        {
            m_bIsInitSucc = FALSE;
        }
    }
}

ParseUrl::~ParseUrl()
{
    WSACleanup();

    if (NULL != m_szICMPData)
    {
        free(m_szICMPData);
        m_szICMPData = NULL;
    }
}

BOOL ParseUrl::Ping(DWORD dwDestIP, PingReply *pPingReply, DWORD dwTimeout)
{
    return PingCore(dwDestIP, pPingReply, dwTimeout);
}

BOOL ParseUrl::Ping(char *szDestIP, PingReply *pPingReply, DWORD dwTimeout)
{
    if (NULL != szDestIP)
    {
        return PingCore(inet_addr(szDestIP), pPingReply, dwTimeout);
    }
    return FALSE;
}

BOOL ParseUrl::PingCore(DWORD dwDestIP, PingReply *pPingReply, DWORD dwTimeout)
{
    //判断初始化是否成功
    if (!m_bIsInitSucc)
    {
        return FALSE;
    }

    //配置SOCKET
    sockaddr_in sockaddrDest;
    sockaddrDest.sin_family = AF_INET;
    sockaddrDest.sin_addr.s_addr = dwDestIP;
    int nSockaddrDestSize = sizeof(sockaddrDest);

    //构建ICMP包
    int nICMPDataSize = DEF_PACKET_SIZE + sizeof(ICMPHeader);
    ULONG ulSendTimestamp = GetTickCountCalibrate();
    USHORT usSeq = ++s_usPacketSeq;
    memset(m_szICMPData, 0, nICMPDataSize);
    ICMPHeader *pICMPHeader = (ICMPHeader*)m_szICMPData;
    pICMPHeader->m_byType = ECHO_REQUEST;
    pICMPHeader->m_byCode = 0;
    pICMPHeader->m_usID = m_usCurrentProcID;
    pICMPHeader->m_usSeq = usSeq;
    pICMPHeader->m_ulTimeStamp = ulSendTimestamp;
    pICMPHeader->m_usChecksum = CalCheckSum((USHORT*)m_szICMPData, nICMPDataSize);

    //发送ICMP报文
    if (sendto(m_sockRaw, m_szICMPData, nICMPDataSize, 0, (struct sockaddr*)&sockaddrDest, nSockaddrDestSize) == SOCKET_ERROR)
    {
        return FALSE;
    }

    //判断是否需要接收相应报文
    if (pPingReply == NULL)
    {
        return TRUE;
    }

    char recvbuf[256] = { "\0" };
    while (TRUE)
    {
        //接收响应报文
        if (WSAWaitForMultipleEvents(1, &m_event, FALSE, 100, FALSE) != WSA_WAIT_TIMEOUT)
        {
            WSANETWORKEVENTS netEvent;
            WSAEnumNetworkEvents(m_sockRaw, m_event, &netEvent);

            if (netEvent.lNetworkEvents & FD_READ)
            {
                ULONG nRecvTimestamp = GetTickCountCalibrate();
                int nPacketSize = recvfrom(m_sockRaw, recvbuf, 256, 0, (struct sockaddr*)&sockaddrDest, &nSockaddrDestSize);
                if (nPacketSize != SOCKET_ERROR)
                {
                    IPHeader *pIPHeader = (IPHeader*)recvbuf;
                    USHORT usIPHeaderLen = (USHORT)((pIPHeader->m_byVerHLen & 0x0f) * 4);
                    ICMPHeader *pICMPHeader = (ICMPHeader*)(recvbuf + usIPHeaderLen);

                    if (pICMPHeader->m_usID == m_usCurrentProcID //是当前进程发出的报文
                        && pICMPHeader->m_byType == ECHO_REPLY //是ICMP响应报文
                        && pICMPHeader->m_usSeq == usSeq //是本次请求报文的响应报文
                        )
                    {
                        pPingReply->m_usSeq = usSeq;
                        pPingReply->m_dwRoundTripTime = nRecvTimestamp - pICMPHeader->m_ulTimeStamp;
                        pPingReply->m_dwBytes = nPacketSize - usIPHeaderLen - sizeof(ICMPHeader);
                        pPingReply->m_dwTTL = pIPHeader->m_byTTL;
                        return TRUE;
                    }
                }
            }
        }
        //超时
        if (GetTickCountCalibrate() - ulSendTimestamp >= dwTimeout)
        {
            return FALSE;
        }
    }
}

USHORT ParseUrl::CalCheckSum(USHORT *pBuffer, int nSize)
{
    unsigned long ulCheckSum = 0;
    while (nSize > 1)
    {
        ulCheckSum += *pBuffer++;
        nSize -= sizeof(USHORT);
    }
    if (nSize)
    {
        ulCheckSum += *(UCHAR*)pBuffer;
    }

    ulCheckSum = (ulCheckSum >> 16) + (ulCheckSum & 0xffff);
    ulCheckSum += (ulCheckSum >> 16);

    return (USHORT)(~ulCheckSum);
}

ULONG ParseUrl::GetTickCountCalibrate()
{
    static ULONG s_ulFirstCallTick = 0;
    static LONGLONG s_ullFirstCallTickMS = 0;

    SYSTEMTIME systemtime;
    FILETIME filetime;
    GetLocalTime(&systemtime);
    SystemTimeToFileTime(&systemtime, &filetime);
    LARGE_INTEGER liCurrentTime;
    liCurrentTime.HighPart = filetime.dwHighDateTime;
    liCurrentTime.LowPart = filetime.dwLowDateTime;
    LONGLONG llCurrentTimeMS = liCurrentTime.QuadPart / 10000;

    if (s_ulFirstCallTick == 0)
    {
        s_ulFirstCallTick = GetTickCount();
    }
    if (s_ullFirstCallTickMS == 0)
    {
        s_ullFirstCallTickMS = llCurrentTimeMS;
    }

    return s_ulFirstCallTick + (ULONG)(llCurrentTimeMS - s_ullFirstCallTickMS);
}

测试ping + Ip 代码


void main()
{
    ParseUrl objParseUrl;
    char *szDestIP = "112.80.248.73";
    PingReply reply;

    printf("Pinging %s with %d bytes of data:\n\n", szDestIP, DEF_PACKET_SIZE);
    for (int i = 0; i < 4; i++)
    {
        objParseUrl.Ping(szDestIP, &reply);
        printf("Reply from %s: bytes=%ld time=%ldms TTL=%ld\n", szDestIP, reply.m_dwBytes, reply.m_dwRoundTripTime, reply.m_dwTTL);
        Sleep(500);
    }
}

测试结果

这里写图片描述

这里写图片描述


测试 结合域名解析实际IP地址 GetIpByDomainName方法

void pingIp(char Ip[100])
{
    ParseUrl objParseUrl;
    PingReply reply;

    printf("\nPinging %s with %d bytes of data:\n\n", Ip, DEF_PACKET_SIZE);
    for (int i = 0; i < 4; i++)
    {
        objParseUrl.Ping(Ip, &reply);
        printf("Reply from %s: bytes=%ld time=%ldms TTL=%ld\n", Ip, reply.m_dwBytes, reply.m_dwRoundTripTime, reply.m_dwTTL);
        Sleep(500);
    }
}

void main()
{
    int   nIpCount = 0;
    char  szIpList[50][100];
    char  szDomain[256] = { 0 };
    char  szIp[1024] = { 0 };
    strcpy_s(szDomain, "www.baidu.com");
    GetIpByDomainName(szDomain, szIpList, &nIpCount);

    printf("域名 : %s \n", szDomain);

    for (int i = 0; i < nIpCount; i++)
    {
        pingIp(szIpList[i]);
        strcat_s(szIp, szIpList[i]);
        strcat_s(szIp, "\t");
    }

    printf("\n域名解析IP列表 : %s \n\n", szIp);
}

测试结果

这里写图片描述

注意

以上主要是用到了这个方法

BOOL ParseUrl::Ping(char *szDestIP, PingReply *pPingReply, DWORD dwTimeout)

这个方法中有三个参数,分别是ping的IP ,ping的返回结果以及ping超时时间,这里注意一下dwTimeout的值,在程序中我们默认dwTimeout为2s,即在2s内如果ping失败会不停地ping下去,直到2s结束,如果ping成功了直接返回,所以在ping的过程中调用Ping这个方法可能需要的时间不一样,如果很快就能ping通那么将立即返回,如果ping不通或者需要经过几次尝试才能ping通,那么就需要耗费一定的时间。所以,我们在ping一个IP的时候并不知道能否ping通,而如果我们程序在ping的时候不能阻塞很长时间,这就需要修改dwTimeout的值。

在最近工作中,我需要在界面打开时进行多个IP的ping操作,如果ping操作时间过长,界面将会卡住一段时间,所以这里就需要缩短ping超时的时间,但是并不是一味地将dwTimeout的值缩短越小越好,有时候明明能够ping通,却因为当前网络环境不好,同时dwTimeout的值设置非常小,导致可能ping不通,而dwTimeout的时间越长得到的结果可能更精确一些。所以这些都需要根据当前使用情况进行取舍,对dwTimeout的值进行合理设置。


尾

以上即为本篇文章的内容,通过两段代码结合实现了cmd命令行程序的ping功能,这里我们也可以用来判断当前设备有没有联网,在某些环境需要判断当前设备是否连接互联网是非常有必要的,在Qt QTcpSocket 对连接服务器中断的不同情况进行判定 这篇文章中,我们叙述了提供几种不同的方法检测客户端与服务器断开的几种方法,其中也提到了使用ping方法来判断本机是否联网,其中使用了Qt封装的库,直接调用即可,方便快捷,但是如果不是Qt程序,可以利用此篇文章提供的C++方法。

同时在Qt QTcpSocket 对连接服务器中断的不同情况进行判定 中也提到了一种更直接的方法,通过windows提供的IsNetworkAlive判断本地是否有网络连接,但是不能判断是否能访问互联网,这就需要通过ping 方法来判断了。可以直接在我贡献的资源中下载源码,进行使用。

代码下载

C++ 实现 ping 功能&& 域名(URL)解析实际 IP地址

C++手动实现HTTP POST请求:从Socket到协议解析的完整指南 HTTP协议是互联网应用通信的基石,它定义了客户端与服务器之间请求与响应的标准格式。其工作原理基于TCP连接,通过请求行、头部和正文的结构化文本来交换数据。掌握HTTP底层实现对于构建高性能、可调试的网络应用具有重要价值,尤其在需要深度定制协议或排查复杂网络问题时。在实际工程中,开发者常遇到如“502 Bad Gateway”等服务器错误或“请求被取消”等客户端异常,理解协议细节和网络I/O模型是定位这些问题的关键。本文将从C++标准库和Socket API出发,详解如何手动构建HTTP POST请求、处理 阅读详情

相关推荐

【CPP】学习路线

C++ 学习路线

Raizeroko的博客 1337

C++代码实现网络Ping功能

ping(Packet Internet Groper)分组网间探测。 测试网络连接的主机或路由器之间的连通性。 应用层使用ICMP协议(网际控制报文协议,Internet Control Message Protocol),必须封装在IP协议里统一收发。

菜鸟打怪的博客 1万+

CDN绕过实战:漏洞回链与全网扫描定位真实IP

在网络安全领域,CDN(内容分发网络)通过分布式缓存节点提升网站访问速度与安全性,但也为渗透测试中的资产发现带来了挑战。其核心原理在于将用户请求调度至边缘节点,隐藏源站服务器的真实IP。从技术价值看,准确识别并绕过CDN是信息收集的关键环节,直接决定了后续漏洞探测的深度与广度。应用场景广泛覆盖渗透测试、攻防演练及安全评估。本文聚焦于通过漏洞回链、接口探针等实战方法,结合全网扫描与反向邮件分析,系统性地穿透CDN防护,精准定位核心资产,为安全测试人员提供一套可落地的技术方案。

agcozdwdfvds08078的博客 410

Google搜索引擎(c++实现)

Google搜索引擎

qq_29688979的博客 1478

C语言手动实现HTTP客户端:从Socket到协议解析的底层网络编程实践

网络编程是计算机通信的基石,其核心在于理解TCP/IP协议栈与Socket编程模型。通过Socket API,应用程序能够在传输层建立可靠的字节流连接,实现端到端的数据交换。HTTP作为应用层协议,构建于TCP之上,定义了客户端与服务器间的请求响应格式。掌握手动实现HTTP通信的技术价值在于深入理解网络协议细节、内存管理与I/O模型,这对于开发高性能服务器、嵌入式网络设备及网络安全工具至关重要。本文聚焦C语言实践,通过动态缓冲区管理、分块传输编码解析等热词,详解如何从零构建健壮的HTTP客户端,为学习Ngi

weixin_33859231的博客 429

cpp-httplib HTTP状态码(StatusCode)详解:从原理到实战应用

HTTP状态码是HTTP协议中用于表示请求处理结果的三位数字代码,是客户端与服务器之间通信的核心语义载体。其设计遵循RFC标准,通过1xx、2xx、3xx、4xx、5xx的系列划分,清晰传达了请求的成功、重定向、客户端错误或服务器错误等状态。在工程实践中,正确使用状态码对于构建符合RESTful规范、具备良好可维护性和可调试性的API至关重要,它不仅是API契约的一部分,更是错误诊断和系统监控的关键依据。以cpp-httplib这一轻量级C++ HTTP库为例,其将标准状态码封装为强类型`StatusCod

weixin_33721427的博客 327

C++复习之路24:计算机网络相关4:

1.从浏览器输入URL到执行的全过程 一、进行域名解析(获取IP地址) 域名解析过程:   1、浏览器搜索自己的DNS缓存,缓存中维护了一张域名和IP地址的对应表   2、若没有则搜索操作系统的DNS缓存   3、若没有则操作系统将域名发送到本地域名服务器,本地域名服务器在自己的DNS缓存查找(递归查询)   4、若没有则通过以下方式查找(递归查询/迭代查询)     本地域名服务器向根域名服务器发送请求,根域名服务器返回com/net/cn/org等等的域顶级服务器域名地址     本地

weixin_42067304的博客 2089

使用C++实现Ping命令

在这个示例代码中,我们使用了 socket 函数创建了一个 Raw Socket,该 Socket 使用 IPPROTO_ICMP 表示它将用于发送和接收 ICMP 报文。在这个示例代码中,我们使用了 getaddrinfo 函数来获取 www.baidu.com 的 IP 地址,并使用 inet_ntop 函数将它转换为字符串形式。本文介绍了使用 C++ 实现 Ping 命令的方法,包括获取目标地址的 IP 地址和发送 ICMP 报文并等待响应。Ping 命令的核心是发送 ICMP 报文并等待响应。

CoderHH的博客 988

C++实现HTTP文件下载:从Socket到分块编码的完整实践

HTTP协议作为互联网数据交换的基石,其核心在于客户端与服务器之间基于请求-响应的通信模型。理解其工作原理,不仅需要掌握状态码、请求头、响应头等基本概念,更需要深入网络编程层面,通过Socket编程实现数据的可靠传输。对于追求极致性能或需要在资源受限环境中运行的场景,直接使用底层API进行开发具有重要价值,它能实现对内存、连接和I/O的精细控制。例如,在处理大文件下载或需要实现断点续传、分块传输编码解码等高级特性时,这种底层控制能力尤为关键。本文通过一个具体的C++项目,详细展示了如何从零开始,使用Wins

weixin_30617695的博客 503

C++:实现ping(附完整源码)

C++:实现ping(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 998

C++实现ping功能

NULL 博文链接:https://jacky-dai.iteye.com/blog/2369807

【C/C++笔试练习】DNS设置文件、应用层、Dos攻击、DNS服务、DNS、子网划分、http状态、路由设置、TCP连接、HTTP状态码、剪花布条、客似云来

C/C++笔试练习笔记、DNS设置文件、应用层、Dos攻击、DNS服务、DNS、子网划分、http状态、路由设置、TCP连接、HTTP状态码、剪花布条、客似云来

Crocodile1006的博客 1353

LLaMA-Factory全面指南:从训练到部署

LLaMA-Factory项目是一个专注于大模型训练、微调、推理和部署的开源平台。其主要目标是提供一个全面且高效的解决方案,帮助研究人员和开发者快速实现大模型的定制化需求。简化大模型训练流程:通过提供一系列预设的训练脚本和参数配置,降低用户在训练大模型时的技术门槛,使得即使是初学者也能轻松上手。增强模型微调能力:支持多种微调方法,如LoRA、QLoRA等,使用户能够根据特定任务需求对模型进行精细调整,从而提升模型性能。优化推理和部署体验。

全世界的博客 1万+

从Socket编程到HTTP客户端:C++实现GET/POST请求与网络调试

网络通信是现代软件开发的基础,其核心是建立在TCP/IP协议栈之上的应用层协议。HTTP作为最广泛使用的应用层协议,规定了客户端与服务器之间请求与响应的标准格式。理解HTTP协议的原理,对于排查网络问题、优化应用性能至关重要。通过Socket编程直接实现HTTP客户端,能够深入掌握请求报文组装、响应解析、连接管理等底层细节,这是理解网络库工作原理和调试复杂网络问题的关键技能。在实践中,开发者常遇到如502 Bad Gateway、连接超时等错误,这些往往与请求头格式、TCP连接状态或代理配置相关。本文通过C

weixin_30312563的博客 315

MaxKey+JeecgBoot单点登录实战:手把手教你从零配置到账户同步

本文提供MaxKey与JeecgBoot单点登录(SSO)的实战整合指南。详细讲解从MaxKey应用注册、JeecgBoot前后端改造,到最终实现账户同步的完整步骤,重点解决Shiro配置、令牌交换等关键问题,帮助企业构建统一、可扩展的身份管理体系。

weixin_29258297的博客 542

拌合楼管理软件开发(十一) 海康威视车牌识别摄像头安装调试,总算是跑通了。

/保存的文件个数这里之所以需要用到委托,直接更新textbox文本中的内容,以及复制picturebox的image会提示不是从齐创建的线程调用。

morsth的博客 4818

C++用Curl实现TCP端口连通性探测的工程实践

TCP端口探测是网络健康检查的基础能力,其本质是验证目标IP与端口之间能否完成三次握手。传统方案如原生socket编码复杂、跨平台兼容性差,系统命令调用(如telnet、nc)则存在进程隔离、输出不一致和嵌入式环境缺失等工程瓶颈。基于libcurl的探测方案,利用CURLOPT_NOBODY与毫秒级超时控制,在不依赖应用层协议的前提下,精准实现TCP连接建立检测,兼具高鲁棒性、细粒度错误分类及SSL/代理复用能力。本文聚焦C++工程落地,覆盖IPv4/IPv6安全解析、私有地址过滤、多线程初始化管理、cur

weixin_34074740的博客 368

《FreeRTOS 入门与实战》第2章:开发环境搭建(实战)

STM32CubeIDE工程创建与FreeRTOS移植J-Link调试环境搭建SystemView可视化跟踪配置。

2301_79143213的博客 1733

C++后端开发学习路线及推荐学习时间

先说一下实习面试的结果吧,本人申请岗位为C++后端开发,通过面试的公司有CVTE、搜狐、字节跳动,然后腾讯明天三面,准备去字节了(不要问我为啥去字节,钱多福利好)。

weixin_49199646的博客 2万+

Nova — GPU/vGPU 虚拟机

目录 文章目录目录云主机使用显卡的实现方式虚拟显卡物理显卡直通物理显卡虚拟化 云主机使用显卡的实现方式 采用虚拟显卡 采用物理显卡直通 采用物理显卡虚拟化 虚拟显卡 虚拟显卡技术,主要用于虚拟机 Remote Console 领域,如:VNC(Virtual Network Computing,虚拟网络计算机),它能将完整的窗口界面通过网络,传输到另一台计算机的屏幕上。 VNC 主要由 VNC server 和 VNC viewer 两部分组成。用户需先将 VNC server 安装在被远程操控的计算

烟云的计算 2428

OpenCloudOS9操作系统搭建Confluence8.2.1+Jira企业级WIKI

Atlassian Confluence是一个专业的企业知识管理与协同软件,可用于构建企业wiki

背锅神童的博客 1023
上一篇: 使用char型数组过程中遇到的问题
下一篇: CString与char*互转、ANSI 和 UNICODE 编码及_T和L宏定义的介绍
前行中的小猪
前行中的小猪 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄10年 4万+粉丝 134原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值