Posted on 2011-11-22 11:55
Onway 阅读(638)
评论(0) 编辑 收藏 引用 所属分类:
使用说明
/*
* http.c by Onway 2011-11-14
* 1,间隔1秒的两次connect避免瞬间造成的错误
* 2,网络读写超时限制参考自《UNIX环境高级编程》第二版中文版程序清单10-8,
* 由于程序是单线程,避免进程堵塞。
* 3,返回值说明
* 0 正确返回
* 1 网络连接失败
* 2 网络IO超时
* 3 时钟注册失败
*/
#include "global.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <setjmp.h>
#define PORT 80
#define BUFFSIZE 10086
static void sig_alrm(int);
static jmp_buf env_alrm;
int QueryWord(const GString *word,const GString *ip,
GString *gstrHtml)
{
g_string_erase(gstrHtml,0,-1);
/* http 请求 */
GString *request = g_string_new("GET /search?q=");
g_string_append(request,word->str);
g_string_append(request,"\
&ue=utf8&keyfrom=dict.index HTTP/1.1\r\n\
Host: dict.youdao.com\r\n\
Connection: close\r\n\
\r\n");
/* 网络地址 */
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(ip->str);
address.sin_port = htons(PORT);
/* 网络连接 */
int socketfd = socket(AF_INET,SOCK_STREAM,0);
if(connect(socketfd,(struct sockaddr *)&address,sizeof(address)) != 0)
{
sleep(1);
if(connect(socketfd,(struct sockaddr *)&address,sizeof(address)) != 0)
{
g_string_free(request,TRUE);
return 1;
}
}
/* 信号注册 */
if(signal(SIGALRM,sig_alrm) == SIG_ERR)
{
g_string_free(request,TRUE);
close(socketfd);
return 3;
}
if(setjmp(env_alrm) != 0)
{
g_string_free(request,TRUE);
close(socketfd);
return 2;
}
/* 网络IO */
alarm(3);
write(socketfd,request->str,request->len);
char buf[BUFFSIZE];
int n;
while( (n = read(socketfd,buf,BUFFSIZE)) > 0 )
g_string_append_len(gstrHtml,buf,n);
alarm(0);
/* 正常返回 */
g_string_free(request,TRUE);
close(socketfd);
return 0;
}
static void sig_alrm(int signo)
{
longjmp(env_alrm,1);
}