国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

10. Linux下實(shí)現(xiàn)簡(jiǎn)單的http客戶端請(qǐng)求

這篇具有很好參考價(jià)值的文章主要介紹了10. Linux下實(shí)現(xiàn)簡(jiǎn)單的http客戶端請(qǐng)求。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

本文Linux下實(shí)現(xiàn)簡(jiǎn)單的http客戶端請(qǐng)求

HTTP(超文本傳輸協(xié)議)是一種用于在網(wǎng)絡(luò)上進(jìn)行數(shù)據(jù)通信的協(xié)議。HTTP 協(xié)議定義了客戶端和服務(wù)器之間如何交換信息,包括請(qǐng)求和響應(yīng)格式、使用的方法、狀態(tài)碼等。
在 HTTP 協(xié)議中,資源(Resource)指的是由 URL (統(tǒng)一資源定位符)所標(biāo)識(shí)的任意可用于訪問的信息。這些信息可以是各種不同類型的數(shù)據(jù),例如:HTML 頁面、圖片、音頻、視頻等多媒體文件、JavaScript 文件、樣式表文件(CSS)、XML 文件、JSON 數(shù)據(jù)。
要完成一個(gè)完整的 HTTP 網(wǎng)絡(luò)通信過程,需要使用以下一系列函數(shù)

  1. socket():創(chuàng)建套接字。

  2. connect():連接到指定的服務(wù)器。

  3. send():向服務(wù)器發(fā)送請(qǐng)求報(bào)文。

  4. listen():監(jiān)聽(多個(gè))io里面有沒有可讀(或可寫)的數(shù)據(jù)

  5. recv():從服務(wù)器接收響應(yīng)報(bào)文。

  6. close():關(guān)閉套接字,釋放資源。

簡(jiǎn)單的http客戶端請(qǐng)求主要函數(shù)如下,詳細(xì)可看代碼里面的注釋

  • char *host_to_ip(const char*hostname):該函數(shù)用于將主機(jī)名(hostname)轉(zhuǎn)換為 IP 地址。
  • int http_create_socket(char *ip):該函數(shù)創(chuàng)建一個(gè) TCP 套接字,并連接到指定的 IP 地址和端口號(hào)上。
  • char *http_send_request(const char *hostname,const char *resource):該函數(shù)發(fā)送 HTTP 請(qǐng)求并獲取響應(yīng)結(jié)果。

編譯指令文章來源地址http://www.zghlxwxcb.cn/news/detail-565350.html

zxmgcc -o http http.c
./http www.baidu.com /
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

//Linux下的頭文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>


#define BUFFER_SIZE     4096
#define HTTP_VERSION    "HTTP/1.1"
#define CONNETION_TYPE "Connection: close\r\n"

// /*該函數(shù)用于將主機(jī)名(hostname)轉(zhuǎn)換為 IP 地址。它首先調(diào)用 gethostbyname 函數(shù)
// 獲取主機(jī)名對(duì)應(yīng)的地址信息結(jié)構(gòu)體,然后從中提取出 IP 地址信息,并返回一個(gè)指向字符串類型的 IP 地址。*/
char *host_to_ip(const char*hostname){
    /*gethostbyname用于通過主機(jī)名獲取主機(jī)的IP地址信息,
    并返回一個(gè)hostent結(jié)構(gòu)體類型的指針,該結(jié)構(gòu)體包含了主機(jī)名、別名和IP地址等信息。*/
    struct hostent *host_entry = gethostbyname(hostname);

    /*inet_ntoa()函數(shù)是一個(gè)在網(wǎng)絡(luò)編程中常用的函數(shù),它可以將一個(gè)32位整數(shù)IP地址轉(zhuǎn)換成標(biāo)準(zhǔn)的點(diǎn)分十進(jìn)制形式
    struct in_addr是一個(gè)C語言中的數(shù)據(jù)結(jié)構(gòu),用于表示32位IPv4地址。*/
    if (host_entry){
        //h_addr_list 是指向主機(jī)IP地址列表的指針,其類型為 char **
        return inet_ntoa(*(struct in_addr*)*host_entry->h_addr_list);
    }
    return NULL;
}

/*該函數(shù)創(chuàng)建一個(gè) TCP 套接字,并連接到指定的 IP 地址和端口號(hào)上。它首先調(diào)用 socket 函數(shù)創(chuàng)建套接字,
然后調(diào)用 connect 函數(shù)連接到目標(biāo)地址。如果成功則返回套接字文件描述符,否則返回 -1。*/
int http_create_socket(char *ip){
    int sockfd=socket(AF_INET,SOCK_STREAM,0);

    //sockaddr_in 用于表示 IPv4 地址和端口號(hào)
    struct sockaddr_in sin={0}; //
    sin.sin_family = AF_INET;   //指定 IP 地址的協(xié)議族
    sin.sin_port=htons(80);  //表示端口號(hào)
    sin.sin_addr.s_addr=inet_addr(ip);//表示 IP 地址,inet_addr作用與inte_ntoa相反

    /*在網(wǎng)絡(luò)編程中,由于不同協(xié)議族(如IPv4、IPv6等)使用不同的地址結(jié)構(gòu)體,為了保證代碼的通用性和可移植性,
    在函數(shù)調(diào)用時(shí)需要將特定協(xié)議族所對(duì)應(yīng)的地址結(jié)構(gòu)體指針轉(zhuǎn)換為通用的 sockaddr 結(jié)構(gòu)體指針。
    因此,當(dāng)我們想要將一個(gè)特定協(xié)議族(如IPv4)的地址結(jié)構(gòu)體傳遞給一個(gè)接受 sockaddr 結(jié)構(gòu)體參數(shù)的函數(shù)時(shí),
    就需要使用 (struct sockaddr*)&sin 進(jìn)行類型強(qiáng)制轉(zhuǎn)換,以避免編譯器報(bào)錯(cuò)。*/
    if ( 0!= connect(sockfd,(struct sockaddr*)&sin,sizeof(struct sockaddr_in))){
        return -1;
    }

    //將 sockfd 文件描述符設(shè)置為非阻塞模式
    fcntl(sockfd, F_SETFL, O_NONBLOCK);

    return sockfd;
}

/*該函數(shù)發(fā)送 HTTP 請(qǐng)求并獲取響應(yīng)結(jié)果。它首先通過 host_to_ip 函數(shù)將主機(jī)名轉(zhuǎn)換為 IP 地址,
然后使用 http_create_socket 函數(shù)創(chuàng)建套接字并連接到目標(biāo)服務(wù)器。接著構(gòu)建 HTTP 請(qǐng)求報(bào)文,
并使用 send 函數(shù)將其發(fā)送給服務(wù)器。最后等待服務(wù)器響應(yīng)并讀取響應(yīng)結(jié)果。*/
char *http_send_request(const char *hostname,const char *resource){
    char *ip=host_to_ip(hostname);
    int sockfd=http_create_socket(ip);

    char buffer[BUFFER_SIZE]={0};

    //HTTP協(xié)議中使用的行結(jié)束符是 "\r\n" ,每個(gè)字段之間需要用兩個(gè)連續(xù)的回車符和換行符 "\r\n\r\n" 分隔開來
	sprintf(buffer, "GET %s %s\r\nHost: %s\r\n%s\r\n\r\n",
        resource, HTTP_VERSION, hostname, CONNETION_TYPE);


    /*如果在使用 UDP 協(xié)議進(jìn)行通信或者需要對(duì)多個(gè)目標(biāo)地址進(jìn)行發(fā)送數(shù)據(jù)操作,則應(yīng)該選擇使用 sendto 函數(shù);
    如果在使用 TCP 協(xié)議進(jìn)行通信且只涉及一個(gè)目標(biāo)地址,則可以選擇使用 send 函數(shù)。*/
    send(sockfd,buffer,strlen(buffer),0);


    /*fd_set 是一個(gè)數(shù)據(jù)類型,可以同時(shí)監(jiān)視多個(gè)文件描述符的狀態(tài),比如可讀、可寫或者異常等。
    在使用前必須先通過FD_ZERO宏清空,并使用FD_SET來添加或刪除其中的文件描述符*/
    fd_set fdread;
    FD_ZERO(&fdread);
    FD_SET(sockfd,&fdread);

    /*timeval 結(jié)構(gòu)體是一個(gè)用于表示時(shí)間的結(jié)構(gòu)體,tv_sec 表示秒數(shù),tv_usec 表示微秒數(shù)*/
    struct timeval tv;
    tv.tv_sec=5;
    tv.tv_usec=0;

    char *result=malloc(sizeof(int));
    memset(result,0,sizeof(int));
    while (1){
        /*select函數(shù)可以監(jiān)聽多個(gè)文件描述符(包括Socket),并等待其中任意一個(gè)或多個(gè)文件描述符上有I/O事件發(fā)生時(shí)通知調(diào)用者
        通過使用select函數(shù),程序可以同時(shí)監(jiān)聽多個(gè)I/O事件,并且只要有任何一個(gè)事件發(fā)生了變化就會(huì)被立即通知。
        這樣可以大大提高程序的性能和響應(yīng)速度,避免阻塞或死循環(huán)等問題*,具體參數(shù)分別如下:
        nfds:需要監(jiān)聽的文件描述符最大值+1。即所有待監(jiān)聽文件描述符中最大的那個(gè)數(shù)加一。
        readfds:指向fd_set類型的指針,用于設(shè)置需要檢查可讀性的文件描述符集合。
        writefds:指向fd_set類型的指針,用于設(shè)置需要檢查可寫性的文件描述符集合。
        exceptfds:指向fd_set類型的指針,用于設(shè)置需要檢查異常條件(錯(cuò)誤)的文件描述符集合。
        timeout:等待超時(shí)時(shí)間。如果為NULL,則表示無限等待;如果為0,則表示立即返回。*/
        int selection=select(sockfd+1,&fdread,NULL,NULL,&tv);
        if( !selection || !FD_ISSET(sockfd,&fdread)){
            break;
        }
        else{
            //buffer之前已經(jīng)被send之后,需要清空
            memset(buffer,0,BUFFER_SIZE);
            int len=recv(sockfd,buffer,BUFFER_SIZE,0);
            if (len==0){
                break;
            }
            
            result=realloc(result,(strlen(result)+len+1)*sizeof(char));
            strncat(result,buffer,len); //strncat()將指定長(zhǎng)度的字符串追加到目標(biāo)字符串末尾
        }
    }
    return result;
}


int main(int argc, char *argv[]) {

	if (argc < 3) return -1;

	char *response = http_send_request(argv[1], argv[2]);
	printf("response : %s\n", response);

	free(response);
	
}

到了這里,關(guān)于10. Linux下實(shí)現(xiàn)簡(jiǎn)單的http客戶端請(qǐng)求的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Linux系統(tǒng)編程,使用C語言實(shí)現(xiàn)簡(jiǎn)單的FTP(服務(wù)器/客戶端)

    Linux系統(tǒng)編程,使用C語言實(shí)現(xiàn)簡(jiǎn)單的FTP(服務(wù)器/客戶端)

    前言 跟著上官社長(zhǎng) 陳哥花了一個(gè)月的時(shí)間終于把Linux系統(tǒng)編程學(xué)的差不多了,這一個(gè)月真的是頭疼啊,各種bug,調(diào)的真心心累,不過好在問題都解決掉了,在此也感謝一下答疑老師,給我提供了很多的思路,本文章是對(duì)前段時(shí)間學(xué)習(xí)Linux,做一個(gè)小小的總結(jié),才疏學(xué)淺,只學(xué)

    2024年02月12日
    瀏覽(24)
  • java代碼構(gòu)建簡(jiǎn)單http服務(wù)器和客戶端

    java代碼構(gòu)建簡(jiǎn)單http服務(wù)器和客戶端

    初識(shí)http a、超文本傳輸 、應(yīng)用層的面向?qū)ο蟮膮f(xié)議,概念介紹網(wǎng)上資源一大堆,關(guān)鍵是基于TCP/IP通信協(xié)議來傳遞數(shù)據(jù)。 b、一開始接觸web項(xiàng)目,都是先接觸的servlet,tomcat服務(wù)器默認(rèn)實(shí)現(xiàn)的一套http規(guī)范,提供了基礎(chǔ)服務(wù)和組件環(huán)境,直接拿到請(qǐng)求、構(gòu)建正文、響應(yīng)客戶端 然而

    2024年02月10日
    瀏覽(28)
  • `accept` 是一個(gè) HTTP 請(qǐng)求頭字段,用于指定客戶端可接受的內(nèi)容類型

    `accept` 是一個(gè) HTTP 請(qǐng)求頭字段,用于指定客戶端可接受的內(nèi)容類型

    accept 是一個(gè) HTTP 請(qǐng)求頭字段,用于指定客戶端可接受的內(nèi)容類型。在 JavaScript 中,可以使用 fetch API 發(fā)送帶有 Accept 頭的請(qǐng)求。例如: 續(xù)寫 當(dāng)然可以,以下是一些關(guān)于 accept 請(qǐng)求頭的更多信息: 使用不同的內(nèi)容類型 除了 application/json ,你還可以使用其他內(nèi)容類型來指定客戶

    2024年02月22日
    瀏覽(24)
  • Http 響應(yīng)頭 Transfer-Encoding : chunked 導(dǎo)致 瀏覽器客戶端請(qǐng)求錯(cuò)誤問題

    Http 響應(yīng)頭 Transfer-Encoding : chunked 導(dǎo)致 瀏覽器客戶端請(qǐng)求錯(cuò)誤問題

    生產(chǎn)環(huán)境服務(wù)器規(guī)劃如下 服務(wù)器 類型 網(wǎng)絡(luò)環(huán)境 cal.com nginx 外網(wǎng) 192.168.7.15:9200 tomcat 內(nèi)網(wǎng) 192.168.7.16:9200 tomcat 內(nèi)網(wǎng) sdd.com nginx 內(nèi)網(wǎng) 192.168.7.15:9100 tomcat 內(nèi)網(wǎng) 192.168.7.16:9100 tomcat 內(nèi)網(wǎng) 192.168.7.15和192.168.7.16是做個(gè)負(fù)載均衡。目前的需求是用戶訪問外網(wǎng)的cal.com 返回 內(nèi)網(wǎng) 192.168.7.15:9

    2024年02月15日
    瀏覽(25)
  • JAVA使用WebSocket實(shí)現(xiàn)多客戶端請(qǐng)求

    工作前提:兩個(gè)服務(wù)之間實(shí)現(xiàn)聊天通訊,因?yàn)榻橛趦蓚€(gè)服務(wù),兩個(gè)客戶端 方案1:多個(gè)服務(wù)端,多個(gè)客戶端,使用redis把用戶數(shù)據(jù)ip進(jìn)行存儲(chǔ),交互拿到redis數(shù)據(jù)進(jìn)行推送 方案2: 一個(gè)服務(wù)端,多個(gè)客戶端,拿到客戶端的id和需要推送的id進(jìn)行拼接存儲(chǔ) 此文章使用的是方案2 1. 引

    2024年02月11日
    瀏覽(18)
  • linux搭建http源【服務(wù)端和客戶端詳細(xì)說明】

    linux搭建http源【服務(wù)端和客戶端詳細(xì)說明】

    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 [root@master ~]# 關(guān)閉防火墻和selinux firewall的話,直接 systemctl stop firewalld 即可 如果使用的是iptables,則吧firewalld替換成iptables [root@master ~]# systemctl is-active firewalld active [root@master ~]# [root@master ~]# systemctl stop firewalld [root@master ~]# [root@m

    2024年04月13日
    瀏覽(33)
  • 客戶端請(qǐng)求+返回 服務(wù)端之間的請(qǐng)求和返回 實(shí)現(xiàn)rpc通信

    背景: ? ? ? ? 1.無論什么類型的游戲,我們都會(huì)有rpc通信的需求。 ? ? ? ? 2.由于客戶端直連的是游戲服,如果工會(huì),匹配之類的服務(wù)是單獨(dú)的服務(wù)的話,必然要進(jìn)行游戲服到業(yè)務(wù)服之間的轉(zhuǎn)發(fā),我們是否需要再轉(zhuǎn)發(fā)時(shí)單獨(dú)定義Req和Res就是我們考慮到的需求。 ? ? ? ? 3.在

    2024年01月25日
    瀏覽(19)
  • linux搭建http源【服務(wù)端和客戶端詳細(xì)說明(1)

    linux搭建http源【服務(wù)端和客戶端詳細(xì)說明(1)

    我下面的HTTP配置使用的包就是iso鏡像里面的包【同理,我們只要會(huì)這種方式以后,使用什么包都一樣,可以自己在網(wǎng)上下載自己需要的包和依賴,然后通過這種方式配置成http源,然后就可以直接使用yum安裝了,這樣的好處是解決軟件在安裝的時(shí)候會(huì)有許多依賴包這個(gè)繁瑣的

    2024年04月11日
    瀏覽(25)
  • Linux 基于 TCP 協(xié)議的簡(jiǎn)單服務(wù)器-客戶端應(yīng)用

    Linux 基于 TCP 協(xié)議的簡(jiǎn)單服務(wù)器-客戶端應(yīng)用

    目錄 一、相關(guān)函數(shù)? 1、listen() 2、accept() 3、connect()? 4、兩種IP地址轉(zhuǎn)換方式? 5、TCP和UDP數(shù)據(jù)發(fā)送和接收函數(shù)對(duì)比 5、log.hpp自定義記錄日志 二、udp_server.hpp單進(jìn)程版本 三、tcp_server.cc 四、Telnet客戶端(代替tcp_client.cc) 五、多進(jìn)程實(shí)現(xiàn)udp_server.hpp 1、多進(jìn)程版本一 2、tcp_client.

    2024年04月27日
    瀏覽(31)
  • 使用HTTP/2實(shí)現(xiàn)服務(wù)端主動(dòng)推送消息給客戶端

    使用HTTP/2實(shí)現(xiàn)服務(wù)端主動(dòng)推送消息給客戶端

    77. 使用HTTP/2實(shí)現(xiàn)服務(wù)端主動(dòng)推送消息給客戶端 HTTP/2 協(xié)議的服務(wù)器主動(dòng)推送機(jī)制是通過服務(wù)器在接收到客戶端請(qǐng)求后,主動(dòng)向客戶端推送相關(guān)資源的方式來實(shí)現(xiàn)的。下面將詳細(xì)解釋如何在服務(wù)器端和客戶端實(shí)現(xiàn) HTTP/2 的服務(wù)器主動(dòng)推送,并給出相應(yīng)的代碼示例。 客戶端實(shí)現(xiàn):

    2024年02月11日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包