和我的上一篇文章是一起写的,呵呵,大家给提点意见啊。
:-)
/*********filename :
Client.cpp****************
该程序通过标准socket实现HTTP/1.0协议
运行该程序可以通过GET
方法取得Head域并将
所请求的内容存储到本地
**********************************************/
#include <winsock.h>
#include <iostream>
#define HTTP_PORT
80 //HTTP连接的默认端口号
#define
MAXSIZE
256 //自定义的每次传输数据的最大数量
using namespace std;
/*
* 这个方法构造本地SOCKET
*
@return
* 返回构造好的socket描述符
*/
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
}
/**************************************
该方法包装了send()
通过该方法发送数据
能够全部发出
没有遗漏
**************************************/
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
}
/**************************************
主函数main()
整个程序的入口
**************************************/
void
main() {
/*
* 调用WSAStartup() 便于访问sockets
library
*/
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; //远程服务器的地址信息
/*
* 主循环
* 直到用户输入q
退出循环
*/
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)
{
/********************
提取head信息
********************/
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);
}
}
/*********程序结束Client.cpp***********/
C语言实现Web客户端(转-kungstriving),布布扣,bubuko.com
C语言实现Web客户端(转-kungstriving)
原文:http://www.cnblogs.com/sanchrist/p/3573297.html