當前位置:編程學習大全網 - 編程語言 - Linux中怎麽用C語言打開網頁

Linux中怎麽用C語言打開網頁

給妳壹個哈,我自己調試好的,並且加了詳細註釋~~記得給分啊,我沒分問問題了~

#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 超時返回

這裏使用的辦法是設置壹個時鐘,如果gethostbyname在指定的時間內尚未返回,

時鐘會強制其返回,得到的返回值顯然是空指針,等價於告訴用戶主機未連如互聯網或者該域名無法解析。*/

static sigjmp_buf jmpbuf;

static void alarm_func() //該函數執行之後會執行跳轉

{

siglongjmp(jmpbuf, 1);

}

static struct hostent *gngethostbyname(char *HostName, int timeout)

{

struct hostent *lpHostEnt;

signal(SIGALRM, alarm_func); //接受alarm信號,然後調用函數

if(sigsetjmp(jmpbuf, 1) != 0)//跳轉目的地

{

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編程實現connect超時的壹種方法

創建套接字,將其設置成非阻塞狀態。

調用connect連接對端主機,如果失敗,判斷當時的errno是否為EINPROGRESS,也就是說是不是連接正在進行中,如果是,轉到步驟3,如果不是,返回錯誤。

用select在指定的超時時間內監聽套接字的寫就緒事件,如果select有監聽到,證明連接成功,否則連接失敗。*/

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

{

//最好檢查壹下參數,要求傳入3個參數 URL PORT TIMEOUT(connect && send && recv 3個參數的超時)

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); //解析域名的超時設置,測試域名超時,可以寫壹個可以ping的通但是沒有辦法解析域名

//的IP地址到resolv.conf裏面,然後加上壹個默認路由,直接PING壹個百度,就能發現如果不加超時機制就會壹直卡在那裏

if(NULL == site)

{

printf("\ncan not find the site!\n");

return -2;

}

fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); //設置為非阻塞模式

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)

{

//調用壹次系統函數失敗後直接看errno,確定是什麽問題,下面的代碼可以實現在沒有默認路由的情況下直接返回失敗.

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時間內是阻塞模式,超過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); //設置為阻塞模式

//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的時候,拔掉網線就可以測試出recv超時的功能,如果不加recv 的超時功能,拔掉網線後就會壹直卡在那裏,當然妳在實際應用的時候沒必要加這個

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;

}

  • 上一篇:假設論證的具體例子
  • 下一篇:恐怖視頻:海獅為何將小女孩拖下水
  • copyright 2024編程學習大全網