如何利用socket進行HTTP訪問——————————-http://blog

來源:互聯網
上載者:User
如何利用  socket  進行  HTTP  訪問平常我們要訪問某個 URL 一般都是通過瀏覽器進行:提交一個 URL 請求後,瀏覽器將請求發向目標伺服器或者Proxy 伺服器,目標伺服器或者Proxy 伺服器返回我們所需要的資料,瀏覽器接收到這些資料後儲存成檔案並進行顯示。下面我們看看如何自己利用 winsock2.h 中的介面來實現這個功能?為了簡化問題,作以下假設:通過Proxy 伺服器進行 HTTP 訪問,這樣就省去了對 URL 進行 DNS 解析的步驟,假設Proxy 伺服器的地址為: 192.168.0.1 : 808 。 這個功能由以下幾個部分組成:1.  如何建立串連?2.  如何發送請求?3.  如何接收資料?4.  如何判斷資料接收完成? 下面我們依次來看下這些問題如何解決? 一、  如何建立與伺服器之間的串連HTTP 基本 TCP ,所以我們需要與伺服器建立串連,然後才能發送資料。建立串連參考如下函數 socket_open :/** 開啟Socket,返回socketId,-1表示失敗*/int socket_open(int IP,int Port,int type){SOCKET socketId; struct sockaddr_in serv_addr;  int status;  socketId=socket(AF_INET,SOCK_STREAM,0);  if ((int )socketId<0) {       printf("[ERROR]Create a socket failed!\n" );       return -1; }  memset(&serv_addr,0,sizeof (serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_addr.s_addr = ntohl(IP); serv_addr.sin_port = htons((USHORT)Port); status=connect(socketId,(struct sockaddr*)&serv_addr,sizeof (serv_addr));    if (status!=0) {    printf("[ERROR]Connecting failed!\n" );    closesocket(socketId);    return -1; } return socketId;}         調用方式如下:int socketId=socket_open( 0xC0A80001,808,0); //0xC0A80001 是192.168.0.1的十六進位寫法。 二、  如何發送請求發送資料要根據 HTTP 協議的要求附加協議頭:static const char * protocolHead="GET http://www.xxx.com/index.html HTTP/1.1\n"     "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\n"     "Accept-Language: zh-cn\n"     "User-Agent:iPanelBrowser/2.0\n"     "Host: www.xxx.com:80\n"     "Connection: close\n\n"     這裡使用GET來擷取指定URL的指定文檔。     建立串連後使用send將這些資料發送出去:     send(socketId, protocolHead,strlen(protocolHead),0);     發送完成HTTP請求後就等待接收資料。       三、  如何接收資料這裡採用 select 迴圈查詢的方式來判斷有無資料到來: struct timeval tm = {0,7};     fd_set fds_r;     int status;     char recvBuf[4096]={ ‘ \0’};     FD_ZERO(&fds_r);     FD_SET(socketId,&fds_r);    status=select(socketId+ 1, &fds_r, 0, 0, &tm); //socketId 在這裡是最大的fd         if (status > 0 && FD_ISSET(socketId, &fds_r)){         printf("Socket is readable...fd=[%d]\n" ,socketId);          recv(socketId,recvBuf,4096,0);} 這樣資料包就儲存到緩衝區中了。  四、  如何判斷資料接收完成首先對返回資料的狀態進行判斷,僅當狀態為“ HTTP 200 OK ”時才表明正確返回,這時才對資料進行解析並儲存,如果狀態為 HTTP 404 NOT FOUND 或者其它狀態則表明沒有找到資源或者出現其它問題,可參考  HTTP 1.1狀態碼及其含義 。當資料正確返回時,為了將實際資料從協議中分離出來進行儲存,需要對 HTTP 資料包進行解析得到 Content-Length ,然後在包含 Content-Length 的當前資料包或者隨後的資料包中尋找第一個空行,這就是內容( Content )的開始位置,再配合前面解析得到的 Content-Length ,就能夠知道什麼時候資料接收完成了。分行符號為“ \r\n ”,也相容“ \n ”或者“ \r ”,設分行符號為 ^P ,則空行如果位於內容中間或結尾則可尋找“ ^P^P ”,若位於開頭,則尋找 ^P 。 基本就是上面這些,這四個問題解決了,那麼整個問題也就解決了!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.