簡單的請求格式

創(chuàng)新互聯(lián)公司于2013年開始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元東臺做網(wǎng)站,已為上家服務(wù),為東臺各地企業(yè)和個人服務(wù),聯(lián)系電話:028-86922220
GET /index.php HTTP/1.0
host:
當(dāng)我們和服務(wù)器連接上之后,發(fā)送上面的數(shù)據(jù)過去,服務(wù)器就會返回 index.php 這個頁面給我們。
GET 這個 是表示 以什么方式請求,HTTP中還有很多其他的請求方式,常用的就 GET POST (更詳細(xì)的 可以點(diǎn)開上面 http協(xié)議 那個鏈接)
GET 后面緊跟一個空格 然后 給出,要獲取的資源的名稱, /index.php 就表示獲取網(wǎng)站服務(wù)器根目錄下 index.php 執(zhí)行后所產(chǎn)生的內(nèi)容,我們也可以改成 GET / HTTP/1.0 這就表示獲取默認(rèn)首頁的內(nèi)容 。 GET /1.html HTTP/1.0 就是獲取 服務(wù)器根目錄下 1.html的內(nèi)容,很容易理解吧。
接下來隔一個空格 跟上 HTTP/1.0 表示 http協(xié)議的版本,這個是固定的 。
第二行 host: 用來指定 訪問哪個主機(jī)。 大家都知道,一個服務(wù)器可以放很多個網(wǎng)站,每個網(wǎng)站有不同的域名,所以我們需要用這個host來指定 我們要訪問的是哪個網(wǎng)站,這樣 才能正確得訪問到我們想訪問的網(wǎng)站。
第一步,連接服務(wù)器。
第二步,按照http協(xié)議,發(fā)送請求數(shù)據(jù),然后就是接受返回的內(nèi)容。
沒錯,就這么簡單。
在編寫程序之前,我們先用一個小工具來模擬一下這個過程,好讓我們對http協(xié)議了解更深入一些。
telnet工具 如果是 win7下的朋友 猛戳這里--win7開啟telnet功能
到此為止,我假設(shè)大家電腦上已經(jīng)開啟了 telnet功能,正題開始。
telnet 他是一個基于tcp/ip 協(xié)議的程序,為我們用戶提供一個 與其他電腦通信的工具,我們可以使用他來和其他電腦進(jìn)行連接通信。
開始-運(yùn)行-輸入telnet回車, 出現(xiàn)一個黑框如下。
我們這時就可以輸入命令,來連接遠(yuǎn)程主機(jī),比如我們這次是要連接我們自學(xué)去論壇 的服務(wù)器,
那么我們就輸入 open 80 然后回車。
open 是打開的意思 后面跟上 要打開那個主機(jī) 然后 后面跟上端口, web服務(wù)器默認(rèn)使用的是80端口,所以 要加上80端口(不加端口 telnet默認(rèn)是23端口)。
然后會出現(xiàn)下圖的情況,這時候 我們就可以輸入命令了,輸入的命令都將被發(fā)送到自學(xué)去論壇的服務(wù)器上面。大家注意一下 下圖紅色箭頭所指出的部分,那里就是一個輸入光標(biāo),不用管其他的字。
這就代表 我們已經(jīng)和遠(yuǎn)程主機(jī)連接上了,就相當(dāng)于我們上節(jié)課中 客戶端執(zhí)行到 connect 函數(shù) 之后 就是要調(diào)用 send函數(shù)發(fā)送數(shù)據(jù)了,在這里 我們只需要按鍵盤輸入到黑色窗口中 就會發(fā)送到服務(wù)端。
我們依次輸入以下內(nèi)容,(注意,不能按退格,輸入錯誤了,就重新打開telnet,重新操作。)
給你一個哈,我自己調(diào)試好的,并且加了詳細(xì)注釋~~記得給分啊,我沒分問問題了~
#include stdlib.h
#include stdio.h
#include unistd.h
#include fcntl.h
#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include errno.h
#include time.h
#include sys/types.h
#include sys/ioctl.h
#include string.h
#include stdarg.h
#include netdb.h
#include setjmp.h
#include signal.h
/*gethostbyname 超時返回
這里使用的辦法是設(shè)置一個時鐘,如果gethostbyname在指定的時間內(nèi)尚未返回,
時鐘會強(qiáng)制其返回,得到的返回值顯然是空指針,等價于告訴用戶主機(jī)未連如互聯(lián)網(wǎng)或者該域名無法解析。*/
static sigjmp_buf jmpbuf;
static void alarm_func() //該函數(shù)執(zhí)行之后會執(zhí)行跳轉(zhuǎn)
{
siglongjmp(jmpbuf, 1);
}
static struct hostent *gngethostbyname(char *HostName, int timeout)
{
struct hostent *lpHostEnt;
signal(SIGALRM, alarm_func); //接受alarm信號,然后調(diào)用函數(shù)
if(sigsetjmp(jmpbuf, 1) != 0)//跳轉(zhuǎn)目的地
{
alarm(0);//timout
signal(SIGALRM, SIG_IGN);
return NULL;
}
alarm(timeout);//setting alarm
printf("\nwill gethost!\n");
lpHostEnt = gethostbyname(HostName);
signal(SIGALRM, SIG_IGN);
return lpHostEnt;
}
/*(linux socket編程實(shí)現(xiàn)connect超時的一種方法
創(chuàng)建套接字,將其設(shè)置成非阻塞狀態(tài)。
調(diào)用connect連接對端主機(jī),如果失敗,判斷當(dāng)時的errno是否為EINPROGRESS,也就是說是不是連接正在進(jìn)行中,如果是,轉(zhuǎn)到步驟3,如果不是,返回錯誤。
用select在指定的超時時間內(nèi)監(jiān)聽套接字的寫就緒事件,如果select有監(jiān)聽到,證明連接成功,否則連接失敗。*/
int main(int argc, char *argv[])
{
//最好檢查一下參數(shù),要求傳入3個參數(shù) URL PORT TIMEOUT(connect send recv 3個參數(shù)的超時)
int fd, retval,res,error;
struct sockaddr_in addr;
struct timeval timeo = {15, 0}; //time ou struct
struct hostent *site;
socklen_t len = sizeof(timeo);
fd_set set;
fd = socket(AF_INET, SOCK_STREAM, 0);
if (argc == 4)
timeo.tv_sec = atoi(argv[3]);
site=gngethostbyname(argv[1],3); //解析域名的超時設(shè)置,測試域名超時,可以寫一個可以ping的通但是沒有辦法解析域名
//的IP地址到resolv.conf里面,然后加上一個默認(rèn)路由,直接PING一個百度,就能發(fā)現(xiàn)如果不加超時機(jī)制就會一直卡在那里
if(NULL == site)
{
printf("\ncan not find the site!\n");
return -2;
}
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); //設(shè)置為非阻塞模式
addr.sin_family = AF_INET;
//addr.sin_addr.s_addr = inet_addr(argv[1]);
memcpy(addr.sin_addr, site-h_addr_list[0], site-h_length);
addr.sin_port = htons(atoi(argv[2]));
printf("%d\n", time(NULL));
/*if (connect(fd, (struct sockaddr*)addr, sizeof(addr)) == 0) {
printf("connected1\n");
// return 0;
}*/
//res=connect(fd, (struct sockaddr*)addr, sizeof(addr));
//printf("\nconnect result:[%d]\n",res);
if (connect(fd, (struct sockaddr*)addr, sizeof(addr)) != 0)
{
//調(diào)用一次系統(tǒng)函數(shù)失敗后直接看errno,確定是什么問題,下面的代碼可以實(shí)現(xiàn)在沒有默認(rèn)路由的情況下直接返回失敗.
if (errno != EINPROGRESS) {
printf("connect:normal network unreach!!");
return -1;
}
printf("\nwill select\n");
FD_ZERO(set);/*將set清零使集合中不含任何fd*/
FD_SET(fd,set); /*將一個給定的文件描述符加入集合之中*/
retval = select(fd + 1, NULL, set, NULL, timeo);
if (retval == -1) {
printf("select");
return -1;
} else if(retval == 0) {
printf("timeout\n"); //這樣的select等于是變成了再timeout時間內(nèi)是阻塞模式,超過timeout就直接返回
printf("%d\n", time(NULL));
return 0;
}
else
{
printf("connected---:[%d]\n",retval);
getsockopt(fd, SOL_SOCKET, SO_ERROR, error, (socklen_t *)len); //判斷在connected成功之后,獲取套接口目前的一些信息來判斷是否真的是連接上了,返回0表示真的連上了
printf("error---:[%d]\n",error);
if(0!=error)
return -1;
}
}
int ul = 0;
ioctl(fd, FIONBIO, ul); //設(shè)置為阻塞模式
//return 0;
setsockopt(fd,SOL_SOCKET,SO_SNDTIMEO,(char *)timeo,sizeof(timeo));
setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(char *)timeo,sizeof(timeo));
printf("\nbefore\n");
sleep(5); //在sleep 5的時候,拔掉網(wǎng)線就可以測試出recv超時的功能,如果不加recv 的超時功能,拔掉網(wǎng)線后就會一直卡在那里,當(dāng)然你在實(shí)際應(yīng)用的時候沒必要加這個
printf("\nafter\n");
char *msg="GET / HTTP/1.0\r\n\r\n";
if( send(fd, msg, strlen(msg), 0)0 )
{
printf("error in send msg\n");
exit(1);
}
int i=0;
char buf[1000];
while((recv(fd,buf,1000,MSG_WAITALL))0)
{
printf("[%d]:[%s]",i,buf);
i++;
}
printf("\n------end---------\n");
close(fd);
return;
}
參考代碼如下:
#include?windows.h
int?main(void)
{
ShellExecute(NULL,?"open",?"",?NULL,?NULL,?SW_MINIMIZE);
return?0;
}
例子中是最小化打開的,還可以是最大化SW_MAXIMIZE,隱藏SW_HIDE等。
新聞標(biāo)題:c語言有訪問網(wǎng)頁的函數(shù)嗎 C語言直接訪問
文章地址:http://chinadenli.net/article2/hijdic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、企業(yè)建站、定制網(wǎng)站、建站公司、營銷型網(wǎng)站建設(shè)、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)