和我的上一篇文章是一起写的,呵呵,大家给提点意见啊。
:-)
/*********filename : Client.cpp****************
该程序通过标准socket实现HTTP/1.0协议
运行该程序可以通过GET 方法取得Head域并将
所请求的内容存储到本地
**********************************************/
该程序通过标准socket实现HTTP/1.0协议
运行该程序可以通过GET 方法取得Head域并将
所请求的内容存储到本地
**********************************************/
#include <winsock.h>
#include <iostream>
#include <iostream>
#define HTTP_PORT 80 //HTTP连接的默认端口号
#define MAXSIZE 256 //自定义的每次传输数据的最大数量
#define MAXSIZE 256 //自定义的每次传输数据的最大数量
using namespace std;
/*
* 这个方法构造本地SOCKET
* @return
* 返回构造好的socket描述符
*/
int make_socket() {
struct sockaddr_in local_addr; //该结构体存储本地地址信息
* 这个方法构造本地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;
}
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);
* 填充本地连接信息
*/
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
}
该方法包装了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;
主函数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; //远程服务器的地址信息
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);
}
* 主循环
* 直到用户输入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);
填充远程服务器的连接信息
*************************************/
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; //连接成功
连接服务器
*************************************/
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;
}
读取客户端命令
******************************/
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); //字节数 限定每次读取一个字节
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);
}
/********************
提取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***********/
稳定、高效、健壮