其实在浏览器看到是正常的,但是通过goldendict访问就不行了,主要表现是导航条工作不正常,不能隐藏,和页面底下出现的一大片空白。如图:
/Files/Onway/eyoudao-web.tar.gz.rargyd-server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <pthread.h>
#define PROT 10000
#define ADDRESS "127.0.0.1"
#define BACKLOG 20
#define BUFSIZE 4096
/* 互斥量,用于各个线程的标准输出 */
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
struct clientinfo
{
int sockfd; /* 客户端套接字 */
int sockno; /* 客户端请求顺序号 */
};
int create_server_socket();
void* handle_request(void*);
int send_dynamic(struct clientinfo*,char*); /* 通过dynamic.bash返回的结果 */
int send_static(struct clientinfo*,char*); /* 直接读文件发送 */
void print_msg(int,const char*); /* 标准输出 */
int
main(int argc,char *argv[])
{
int serverfd;
int count = 0;
pthread_t ptid;
struct clientinfo *cinfo;
/* 创建监听套接字 */
serverfd = create_server_socket();
if (serverfd == -1) {
printf("main(): terminate\n");
return -1;
}
while (1) {
cinfo = (struct clientinfo*) malloc (sizeof(struct clientinfo));
cinfo->sockfd = accept(serverfd,NULL,NULL);
cinfo->sockno = ++count;
pthread_create(&ptid,NULL,handle_request,(void*)cinfo);
}
return 0;
}
int
create_server_socket()
{
int tmpfd = socket(AF_INET,SOCK_STREAM,0);
if (tmpfd == -1) {
printf("create_server_socket(): socket error\n");
return -1;
}
struct sockaddr_in svraddr;
bzero(&svraddr,sizeof(svraddr));
svraddr.sin_family = AF_INET;
svraddr.sin_port = htons(PROT);
svraddr.sin_addr.s_addr = inet_addr(ADDRESS);
if (bind(tmpfd,(struct sockaddr*)&svraddr,sizeof(svraddr)) == -1) {
printf("create_server_socket(): bind error\n");
return -1;
}
if (listen(tmpfd,BACKLOG) == -1) {
printf("create_server_socket(): listen error\n");
return -1;
}
return tmpfd;
}
void*
handle_request(void *info)
{
struct clientinfo *cinfo = (struct clientinfo*) info;
char receive[BUFSIZE << 1] = "";
char method[BUFSIZE] = "",request[BUFSIZE] = "";
char header[] = "HTTP/1.1 200 OK\r\nconnection:close\r\n\r\n";
int i;
if (recv(cinfo->sockfd,receive,BUFSIZE << 1,0) < 0) {
print_msg(cinfo->sockno,"handle_request(): recv error");
return ( (void*) 0);
}
/* 回应报头 */
write(cinfo->sockfd,header,strlen(header));
/* 请求方法和参数的简单检测 */
sscanf(receive,"%s%s",method,request);
if (strcmp(method,"GET")) {
print_msg(cinfo->sockno,"handle_request(): method is not GET");
return ( (void*) 0);
}
if (strlen(request) < 8) {
print_msg(cinfo->sockno,"handle_request(): unknow request");
goto end;
}
print_msg(cinfo->sockno,receive);
/* 请求dynamic.bash */
if (strncmp(request,"/action?",8) == 0) {
send_dynamic(cinfo,request);
goto end;
}
send_static(cinfo,request);
end:
close(cinfo->sockfd);
free(cinfo);
return ( (void*) 0);
}
int
send_static(struct clientinfo *cinfo,char *request)
{
int len = strlen(request);
char path[1024],buf[BUFSIZE];
int fd,bytes;
/* 忽略开头的'/'符号 */
sscanf(request,"%*c%s",path);
/* 文件读取 */
fd = open(path,O_RDONLY);
if (fd == -1) {
print_msg(cinfo->sockno,"send_static(): open error");
return 1;
}
while ((bytes = read(fd,buf,4096)) > 0) {
write(cinfo->sockfd,buf,bytes);
}
close(fd);
return 0;
}
int
send_dynamic(struct clientinfo *cinfo,char *request)
{
char cmd[BUFSIZE],arg[1024],line[BUFSIZE];
FILE *fpin;
/* 忽略action? */
sscanf(request,"%*[^?]%*c%s",arg);
sprintf(cmd,"./dynamic.bash \"%s\"",arg);
/* 从popen返回的FILE指针读取内容发送 */
int cnt = 0;
if ((fpin = popen(cmd,"r")) == NULL) {
print_msg(cinfo->sockno,"send_dynamic(): popen error");
return 1;
}
while (fgets(line,BUFSIZE,fpin) != NULL) {
write(cinfo->sockfd,line,strlen(line));
}
pclose(fpin);
return 0;
}
void
print_msg(int no,const char *msg)
{
pthread_mutex_lock(&lock);
printf("request: %d\n%s\n\n",no,msg);
pthread_mutex_unlock(&lock);
}
dynamic.bash
#!/bin/bash
xmldetail="http://dict.youdao.com/search?keyfrom=deskdict.main&xmlDetail=true&doctype=xml&xmlVersion=7.1&dogVersion=1.0&client=deskdict&appVer=5.0.32.4695&xslVer=3.0&q="
xsldetail="detail/result.xsl"
xmlsimple=""
xslsimple=""
check_in_book() {
# 截断开头结尾的空格,将中间的连续空格换成一个空格
word="`echo $1 | sed 's/^\(%20\)\+//g' | sed 's/\(%20\)\+$//g' | sed 's/\(%20\)\+/ /g'`"
cut -d ';' -f 1 wordsbook | grep -q "^$word$"
[ $? == 0 ] && echo 1 || echo 0
}
add_to_book() {
word="`echo $1 | sed 's/^\(%20\)\+//g' | sed 's/\(%20\)\+$//g' | sed 's/\(%20\)\+/ /g'`"
t="`date +'%y-%m-%d %H:%M'`"
echo "$word;$t;" >> wordsbook
echo 1
}
send_response() {
# $1为:inbook=queryword或者detail=queryword等形式
action=${1%=*}
target=${1#*=}
case $action in
"inbook")
check_in_book "$target"
;;
"tobook")
add_to_book "$target"
;;
"detail")
./xslt "-xmlapi" "$xmldetail" "-xslapi" "$xsldetail" "-keyword" "$target" | sed '$d'
;;
"simple")
;;
*)
exit 1
;;
esac
}
send_response "$1"
exit 0