论坛首页 编程语言技术论坛

Windows下C++实现Web客户端

浏览 8090 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (9) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-04-16   最后修改:2009-06-15
C++
和我的上一篇文章是一起写的,呵呵,大家给提点意见啊。
 
:-)
 
#include <winsock.h>
#include <iostream>
#define HTTP_PORT 80       //HTTP连接的默认端口号
#define MAXSIZE 256        //自定义的每次传输数据的最大数量
using namespace std;

int make_socket() {
 struct sockaddr_in local_addr;    //该结构体存储本地地址信息
 int tempSockId;        //临时变量用来暂时存储socket描述符
 tempSockId = socket(PF_INET, SOCK_STREAM, 0);
 if (tempSockId == -1) {      //如果返回值为-1 则出错
  return tempSockId;
 }
 
 local_addr.sin_family = AF_INET;
 local_addr.sin_port = htons(HTTP_PORT);
 local_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
 memset(&(local_addr.sin_zero), '\0', 8);
 return tempSockId;       //返回取得的SOCKET
}

int sendall(int s, char *buf, int *len) {
 int total = 0;        // 已经发送字节数
 int bytesleft = *len;      // 还剩余多少字节数
 int n;
 while(total < *len) {
  n = send(s, buf+total, bytesleft, 0); // 发送数据
  if (n == -1) { break; }
  total += n;
  bytesleft -= n;
 }
 *len = total;        // 返回实际发送出去的字节数
 return n==-1?-1:0;       // 成功发送返回0 失败-1
}

void main() {
 
 WSADATA wsaData;
 if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
  fprintf(stderr, "WSAStartup failed.\n");
  exit(1);
 }
 
 
 char server[100];       //用来保存用户想要连接的服务器地址
 char command[100];       //用户命令
 char filename[100];       //用户输入的用来保存实体内容的文件名
 char buf[MAXSIZE];       //读取数据的缓存字节数组
 
 FILE * to_store;       //用来存储文件内容的文件指针
 int len = -1;
 struct sockaddr_in remote_server;   //远程服务器的连接信息
 struct hostent * host_info;     //远程服务器的地址信息
 
 while(true) {
  
  int mysocket = make_socket();   //构建本地socket
  
  cout << "Please input the web site you want to connect or 'q' to quit:" << endl; //输出提示信息
  gets(server);       //从控制台读取用户输入
  //cout << server << endl;    //测试用用来输出服务器名称     
  
  if (strcmp(server, "q") == 0) {   //用户输入q 退出程序
   exit(0);
  }
  
  remote_server.sin_family = AF_INET;
  remote_server.sin_port = htons(HTTP_PORT);
  if ((host_info = gethostbyname(server)) == NULL) {     //通过服务器名得到连接信息
   cout << "Server name error or can not be reached!" << endl;  //服务器名称错误或无法连接
   cout << "*********Press any key to continue*************" << endl;//输出提示信息
   char temp[1];
   gets(temp);
   continue;
  }
  remote_server.sin_addr = *((struct in_addr *)host_info->h_addr);
  memset(&(remote_server.sin_zero), '\0', 8);
  
  if (connect(mysocket, (struct sockaddr *)&remote_server,
   sizeof(struct sockaddr)) == -1) {     //连接出错
   cerr << "Connect error!" << endl;
   cout << "*********Press any key to continue*************" << endl;
   char temp[1];
   gets(temp);
   continue;
  }
  
  cout << "Now " << server << " is listening to your command!\n" << endl;  //连接成功
  
  gets(command);
  //cout << command << endl;    //测试用输出命令
 
  
  len = strlen(command);
  if (sendall(mysocket, command, &len) == -1) {
   cout <<"sending error" << endl;  //发送数据出错
   continue;
  }
  cout << "The following is the header" << endl; //输出提示信息
  
  int readed = -1;
  int i = 0;
  bool flag = false;
  readed = recv(mysocket, buf, 1, 0);       //从服务器端读取数据 readed为实际读到的
  //readed = read(mysocket, buf, 1);    //字节数限定每次读取一个字节
  while(readed == 1) {
   
   if (i < 4) {
    if (buf[0] == '\r' || buf[0] == '\n') {  //出现两个\r\n时 i==4
     i++;
    } else {
     i = 0;
    }
    printf("%c", buf[0]);      //把http头信息打印在控制台
   
   } else if (flag) {        //首次进入时
    fwrite(buf, 1, 1, to_store);    //需向用户提示输入存储文件名称
   } else {
    cout << "Please input the filename to store the content file:" << endl;
    gets(filename);
    //cout << filename << endl;     //测试用输出文件名
    to_store = fopen(filename, "w");
    flag = true;
   }
   readed = recv(mysocket, buf, 1, 0);
   //readed = read(mysocket, buf, 1);
  }
  fflush(to_store);
  shutdown(mysocket, 2);
 }
}
   发表时间:2009-06-11   最后修改:2009-06-11
这个是不是C++?
cout << "The following is the header" << endl;

这个是不是C?
printf("%c", buf[0]); 

如果是,怎么混用了?
C新手,希望能得到解答。
0 请登录后投票
   发表时间:2009-06-12  
justshare 写道
这个是不是C++?
cout << "The following is the header" << endl;

这个是不是C?
printf("%c", buf[0]); 

如果是,怎么混用了?
C新手,希望能得到解答。


对,你说的没错,我在这里是混用了一些输出语句,但是都是无关紧要的地方,整个程序的逻辑部分还主要由C完成的
0 请登录后投票
   发表时间:2009-06-12  
我试了一下,为什么在我的C项目中(纯C)不能使用cout?
我用的是Eclipse IDE for C/C++ developers, Version: 3.4.2
编译器:MinGW-5.1.4
0 请登录后投票
   发表时间:2009-06-13  
ANSI/ISO C才是标准C。标准C里面是不包括socket函数和windows API的。

楼主改一下标题就好了——《一个Windows下C++实现的HTTP客户端》,另外,设置一下代码格式吧。
0 请登录后投票
   发表时间:2009-06-15  
joshzhu 写道
ANSI/ISO C才是标准C。标准C里面是不包括socket函数和windows API的。

楼主改一下标题就好了——《一个Windows下C++实现的HTTP客户端》,另外,设置一下代码格式吧。


恩,对,你说的没错
当时起这个题目并没有想太多,看来还是有很多问题的
0 请登录后投票
   发表时间:2009-06-27  
其实用Wininet的话可以更方便地实现下载网页的功能……而且没这么容易出错
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics