在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            博客專欄

            EEPW首頁 > 博客 > 使用 C 語言實(shí)現(xiàn)一個(gè) HTTP GET 連接

            使用 C 語言實(shí)現(xiàn)一個(gè) HTTP GET 連接

            發(fā)布人:電子禪石 時(shí)間:2024-05-16 來源:工程師 發(fā)布文章

             

            如果您比較有耐心,建議從頭至尾讀完這篇文章。如果您只想快速應(yīng)用 C 語言的 HTTP GET 連接功能,可以直接跳到文末拷貝源代碼去使用。

             

            1、HTTP 連接的流程

             

            HTTP 連接都是建立在 TCP 連接之上的。這里我們不討論 TCP 的三次握手四次揮手過程。我們只單純地來分析下一個(gè) HTTP 連接的過程應(yīng)該是怎樣的。

             

            首先,我們需要?jiǎng)?chuàng)建一個(gè) TCP 的 Socket 。后面我們的網(wǎng)絡(luò)連接操作都是基于這個(gè) Socket 來構(gòu)建的。

             

            其次,我們需要來組裝一下 HTTP 請(qǐng)求。就是封裝一個(gè) GET 請(qǐng)求,表明一下我們想要連接哪個(gè)服務(wù)器的哪些資源。當(dāng)然,其實(shí)第 1 步和第 2 步的順序并不重要。

             

            第三步,我們需要發(fā)送 HTTP GET 請(qǐng)求了,將前面封裝好的請(qǐng)求信息通過前面創(chuàng)建好的 TCP 通道發(fā)送出去。

             

            第四步,讀取服務(wù)端的返回結(jié)果。

             

            2、代碼實(shí)操

             

            1、創(chuàng)建 Socket
            復(fù)制代碼
                int sockfd;     
                 //創(chuàng)建套接字
                if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
                    printf("socket failed!!!\n");
                    exit(0);
                }
            復(fù)制代碼

            沒什么好說的,照著做就好了。

             

            2、封裝 HTTP 請(qǐng)求
            復(fù)制代碼
                char request[512] = {0};
                memset(request, 0, 512);
                strcat(request, "GET ");
                strcat(request, "/index.html");
                strcat(request, " HTTP/1.1\n");
                strcat(request, "Host: ");
                strcat(request, "192.168.221.30");
                strcat(request, "\nContent-Type: text/html\n");
                strcat(request, "Content-Length: 0\n");
                strcat(request, "\r\n");
            復(fù)制代碼

            上面加粗標(biāo)灰底的部分分別是要訪問的資源路徑以及服務(wù)器地址。其中服務(wù)器地址并不是很重要,但是上面的資源路徑一定不能錯(cuò)!

             

            3、發(fā)起 HTTP 請(qǐng)求
            復(fù)制代碼
                struct sockaddr_in servaddr;    int writeRet;
                
                bzero(&servaddr, sizeof(servaddr));
                servaddr.sin_family = AF_INET;
                servaddr.sin_port = htons(80);    
                if (inet_pton(AF_INET, "192.168.221.30", &servaddr.sin_addr) <= 0 ){
                    printf("inet_pton error!\n");
                    exit(0);
                }    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){
                    printf("connect error!\n");
                    exit(0);
                }
            
                writeRet = write(sockfd, request, strlen(request));    if (writeRet < 0) {
                    printf("make http error:%d,%s\n", errno, strerror(errno));
                    exit(0);
                }
            復(fù)制代碼

            上面加粗標(biāo)灰底的地址就很重要了,一定不能填錯(cuò),而且只能填 IP 地址。那個(gè)部分的 inet_pton 函數(shù)的作用是將字符串形式的 IPV4 地址轉(zhuǎn)換成二進(jìn)制形式的。如果是 IPV6 地址,則要用 inet_ntop 函數(shù)。

             

            4、讀取返回結(jié)果
            復(fù)制代碼
                struct timeval tv;    int selectRet = 0;
                fd_set t_set1;
                
                sleep(2);
                
                tv.tv_sec= 0;
                tv.tv_usec= 0;
            
                FD_ZERO(&t_set1);
                FD_SET(sockfd, &t_set1);
                
                selectRet = select(sockfd + 1, &t_set1, NULL, NULL, &tv);    if (selectRet < 0) {
                    close(sockfd);
                    printf("select failed!\n");        return;
                }    if (selectRet > 0){        char buf[4096] = {0};        int readLen = 0;
            
                    memset(buf, 0, 4096);
                    readLen = read(sockfd, buf, 4095); // read once only!
                    printf("readLen:%d\n", readLen);
                    printf("\n\n%s\n\n", buf);
                }
            復(fù)制代碼

            上示代碼最后會(huì)將讀取的結(jié)果保存到 buf 數(shù)組中并打印出來。

             

            5、關(guān)閉 Socket
                close(sockfd);
                
                printf("Bye!\n");

            最后,用完 HTTP 通信以后,一定不要忘記關(guān)閉剛才打開的資源。

             

            筆者這邊通過 nginx 搭建了一個(gè)模擬服務(wù)器,與這份代碼調(diào)試,一切正常。可以在控制臺(tái)上得到如下回復(fù)

            復(fù)制代碼
            hello world-------------GET /index.html HTTP/1.1Host: 192.168.221.30Content-Type: text/html
            Content-Length: 0>>>>>>> success with 90 byte(s) <<<<<<<readLen:850HTTP/1.1 200 OK
            Server: nginx/1.16.0Date: Wed, 08 May 2019 06:13:27 GMT
            Content-Type: text/html
            Content-Length: 612Last-Modified: Tue, 23 Apr 2019 13:09:07 GMT
            Connection: keep-alive
            ETag: "5cbf0e73-264"Accept-Ranges: bytes<!DOCTYPE html>
            <html>
            <head>
            <title>Welcome to nginx!</title>
            <style>
                body {
                    width: 35em;
                    margin: 0 auto;
                    font-family: Tahoma, Verdana, Arial, sans-serif;
                }</style>
            </head>
            <body>
            <h1>Welcome to nginx!</h1>
            <p>If you see this page, the nginx web server is successfully installed and
            working. Further configuration is required.</p>
            
            <p>For online documentation and support please refer to<a href="http://nginx.org/">nginx.org</a>.<br/>Commercial support is available at<a href="http://nginx.com/">nginx.com</a>.</p>
            
            <p><em>Thank you for using nginx.</em></p>
            </body>
            </html>Bye!
            復(fù)制代碼

             

            再接下來,就是根據(jù)自己的實(shí)際需要,去做業(yè)務(wù)層的處理了。

             

            3、完整代碼

             

            復(fù)制代碼
            #include <stdio.h>#include <stdlib.h>#include <sys/socket.h>#include <string.h>#include <netinet/in.h>#include <errno.h>#include "http.h"void main()
            {
                
                printf("hello world\n");    
                // step 1 , create socket
                int sockfd;     
                 //創(chuàng)建套接字
                if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
                    printf("socket failed!!!\n");
                    exit(0);
                }    
                // step 2, package the http request
                char request[512] = {0};
                memset(request, 0, 512);
                strcat(request, "GET ");
                strcat(request, "/index.htm");
                strcat(request, " HTTP/1.1\n");
                strcat(request, "Host: ");
                strcat(request, "www.baidu.com");
                strcat(request, "\nContent-Type: text/html\n");
                strcat(request, "Content-Length: 0\n");
                strcat(request, "\r\n");
                printf("-------------\n%s\n",request);    
                
                // step 3, connect and send http request.
                struct sockaddr_in servaddr;    int writeRet;
                
                bzero(&servaddr, sizeof(servaddr));
                servaddr.sin_family = AF_INET;
                servaddr.sin_port = htons(80);    
                if (inet_pton(AF_INET, "192.168.221.30", &servaddr.sin_addr) <= 0 ){
                    printf("inet_pton error!\n");
                    exit(0);
                }    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){
                    printf("connect error!\n");
                    exit(0);
                }
            
                writeRet = write(sockfd, request, strlen(request));    if (writeRet < 0) {
                    printf("make http error:%d,%s\n", errno, strerror(errno));
                    exit(0);
                }
            
                printf(">>>>>>> success with %d byte(s) <<<<<<<\n", writeRet);    
                
                // step 4, read response
                
                struct timeval tv;    int selectRet = 0;
                fd_set t_set1;
                
                sleep(2);
                
                tv.tv_sec= 0;
                tv.tv_usec= 0;
            
                FD_ZERO(&t_set1);
                FD_SET(sockfd, &t_set1);
                
                selectRet = select(sockfd + 1, &t_set1, NULL, NULL, &tv);    if (selectRet < 0) {
                    close(sockfd);
                    printf("select failed!\n");        return;
                }    if (selectRet > 0){        char buf[4096] = {0};        int readLen = 0;
            
                    memset(buf, 0, 4096);
                    readLen = read(sockfd, buf, 4095); // read once only!
                    printf("readLen:%d\n", readLen);
                    printf("\n\n%s\n\n", buf);
                }
            
                close(sockfd);
                
                printf("Bye!\n");
            }
            復(fù)制代碼

             


             




            *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



            關(guān)鍵詞: http

            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉