socket 和 文件读写函数不能共用?

klggg 2003-04-04 03:28:05
以下代码,作用是得到某个链接的网站内容.但运行 后最后提示
Segmentation fault,网页已被顺利抓下来.
我试过去除最后 那行的 fclose(fp);
就没有出现 Segmentation fault 这种错误提示了。
难道 fclose(fp); 这条函数有什么错误吗?
在线等待 ....

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define MaxRecvLen 500

//定义网站结构
struct DOMAIN
{
char url[255]; //http://www.xh88.com:80/index.php 完整网址
char host[20]; //www.xh88.com 主机地址
int port; //sock 联接的端口号
};
typedef struct DOMAIN domain;

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

//******************* 有关 sock 的变量 *************************

int sock_id; //sock 联接句柄

struct hostent *hostbyname; //主机的信息 结构
struct sockaddr_in remote_addr; //包含远端主机IP地址和端口号的结构


//******************* 有关 无阻塞 select 所用到 的变量 *************************

struct timeval timeout; //用于无阻塞 select 调用 的时间变量
fd_set sockid_readable; //sock 类似联接句柄 传递给 select 有效的连接

domain web_domain; //定义一个 web domain 的结构

char send_str[255]; //保存要发送的字符串
char *tempStr,*recBuf; //临时字串,接收到的字串指针

int recv_numb; //保存远端返回的字串大小
FILE *fp; //文件指针,用于保存从远端得到的数据
char *tmpfile="abc.txt"; //临时文件名

timeout.tv_sec = 1; //设置几秒钟超时
timeout.tv_usec = 500000; //设置几微秒超时
web_domain.port=80; //默认端口 为 80
//******************* 处理命令行的参数 *************************

if(argc<2) //参数不足
{ printf("%s","\n\nExp: ./client http://192.168.1.254:80 \n\n");
exit(1);
}
if(!(tempStr=strstr(argv[1],"http://"))) //必须以 http://开头
{ printf("parameter error!\n");
exit(0);
}
strcpy(web_domain.url,tempStr); //http://www.xh88.com:80/index.php
strcpy(web_domain.host,web_domain.url+7); //www.xh88.com
//处理 host
if((tempStr=strstr(web_domain.host,"/")))
{ *tempStr='\0'; //web_domain.host 里去除:后的东西
}
if((tempStr=strstr(web_domain.host,":")))
{ *tempStr='\0'; //Host 里去除:后的东西
web_domain.port=atoi(tempStr+1); //改写端口
}
//!
printf("%s\n%d\n%s\n",web_domain.host,web_domain.host,web_domain.url);

hostbyname = gethostbyname(web_domain.host); //将基本名字和地址转换
if((sock_id=socket(PF_INET,SOCK_STREAM,0))==-1)
{ perror("socket");
exit(1);
}

//初始化远端要传递的socket
remote_addr.sin_family=AF_INET; //地址族
remote_addr.sin_port=htons(web_domain.port); //端口号
remote_addr.sin_addr=*((struct in_addr *)hostbyname->h_addr); //IP地址
bzero(&(remote_addr.sin_zero),8); //填充0 以保持与struct sockaddr同样大小

//和服务器建立连接
if(connect(sock_id,(struct sockaddr *)&remote_addr,sizeof(remote_addr))==-1)
{ perror("connect");
exit(1);
}
printf("\n\nconnected %s ok!\n\n",web_domain.url);

//创建要发送给远端的字串
sprintf(send_str,"GET %s HTTP/1.1\nAccept: */*\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\nHost: %s\n\n",web_domain.url,web_domain.host);
printf("%s\n\n",send_str);
//开始向服务器发送数据
if(send(sock_id,send_str,strlen(send_str),0)==-1)
{ perror("send");
exit(1);
}
recBuf=malloc(MaxRecvLen); //为储存远端返回的字串的变量申请空间
fp=fopen(tmpfile,"w");
while(1)
{
//设置无堵塞模式
FD_ZERO(&sockid_readable);
FD_SET(sock_id,&sockid_readable);
select(sock_id+1, &sockid_readable, NULL, NULL, &timeout);
if (!FD_ISSET(sock_id, &sockid_readable))
{ printf("Timed out.\n");
break;
}
recv_numb = recv(sock_id,recBuf,MaxRecvLen,0); //得到远端返回的字串
recBuf[recv_numb]='\0';
fputs(recBuf,fp);
//printf("\n\t********* %d *******",recv_numb);
//printf("%s",recBuf);
if(recv_numb<1) //返回的长度不够退出循环
break;
}
printf("\n\nrecv ok!\n\n");
close(sock_id);
fclose(fp);
free(recBuf);
return 0;
}
...全文
26 2 打赏 收藏 举报
写回复
2 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
klggg 2003-04-04
肯定功能的。
在程序里我用fp=fopen(tmpfile,"w");
然后 fputs ..
最后 fclose()
打开当前目录下的
临时文件名 abc.txt 发现里面就是得到的网页内容..
应该可以确定 fp 是有效的.
  • 打赏
  • 举报
回复
blh 2003-04-04
fp=fopen(tmpfile,"w");??
你确定fp是有效的吗,也就是fopen成功吗?
  • 打赏
  • 举报
回复
相关推荐
发帖
Linux/Unix社区
加入

2.1w+

社区成员

Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
申请成为版主
帖子事件
创建了帖子
2003-04-04 03:28
社区公告
暂无公告