Windows下C++实现WEB服务器

上传人:ba****u 文档编号:184377994 上传时间:2023-02-01 格式:DOCX 页数:9 大小:15.94KB
返回 下载 相关 举报
Windows下C++实现WEB服务器_第1页
第1页 / 共9页
Windows下C++实现WEB服务器_第2页
第2页 / 共9页
Windows下C++实现WEB服务器_第3页
第3页 / 共9页
点击查看更多>>
资源描述
自己研究了好几天终于写出来一个,哈哈,当然也从网上得到了很多的帮助拉。 谢谢大家咯!这个版本还不是很完善,但Web服务器的基本框架已经出来了,还 有部分的功能需要进行进一步的测试和修改。虽然说C的开发比较慢,对于程序 员来说比较难以操作,但通过用C写这些很底层的东西,可以更好的了解的象 java的socket中的工作原理。有一定的帮助!以下是源代码: #include #include #include using namespace std;/自定义的服务端口主机名长度/同时等待的连接个数#define SERVER_PORT 10000#define HOSTLEN 256#define BACKLOG 10 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 wrong_req(int sock) (char* error_head = HTTP/1.0 501 Not Implementedrn; /输出 501 错误 int len = strlen(error_head);if (sendall(sock, error_head, &len) = -1) (/向客户发送printf(Sending failed!);return;char* error_type = Content-type: text/plainrn;len = strlen(error_type);if (sendall(sock, error_type, &len) = -1) (printf(Sending failed!);return;char* error_end = rn;len = strlen(error_end);if (sendall(sock, error_end, &len) = -1) (printf(Sending failed!);return;char* prompt_info = The command is not yet completedrn”;len = strlen(prompt_info);if (sendall(sock, prompt_info, &len) = -1) (printf(Sending failed!);return;bool not_exit(char* arguments) (struct stat dir_info;return (stat(arguments, &dir_info) = -1);void file_not_found(char* arguments, int sock) (char* error_head = HTTP/1.0 404 Not Foundrn;/构造 404 错误 headint len = strlen(error_head);if (sendall(sock, error_head, &len) = -1) (/向客户端发送printf(Sending error!);return;char* error_type = Content-type: text/plainrn;len = strlen(error_type);if (sendall(sock, error_type, &len) = -1) (printf(Sending error!);return;char* error_end = rn;len = strlen(error_end);if (sendall(sock, error_end, &len) = -1) (printf(Sending error!);return;char prompt_info50 = Not found: ;strcat(prompt_info, arguments);len = strlen(prompt_info);if (sendall(sock, prompt_info, &len) = -1) (输出未找到的文件printf(Sending error!);return;void send_header(int send_to, char* content_type) (char* head = HTTP/1.0 200 OKrn;/正确的头部信息int len = strlen(head);if (sendall(send_to, head, &len) = -1) (/向连接的客户端发送数据printf(Sending error);return;if (content_type) (/content_type 不为空char temp_130 = Content-type: ;/准备好要连接的字串strcat(temp_1, content_type); /构造 content_type strcat(temp_1, rn);len = strlen(temp_1);if (sendall(send_to, temp_1, &len) = -1) ( printf(Sending error!); return;char* file_type(char* arg) (char * temp;/临时字符串指针if (temp二strrchr(arg,.) != NULL) (/取得后缀return temp+1;return ;/如果请求的文件名中没有.则返回空串void send_file(char* arguments, int sock) (char* extension = file_type(arguments);/获得文件后缀名char* content_type = text/plain;初始化 type=text/plainFILE* read_from;本地文件指针从该文件中读取.html .jpg等int readed = -1;每次读得的字节数if (strcmp(extension, html) = 0) (发送内容为 htmlcontent_type = text/html;if (strcmp(extension, gif) = 0) (发送内容为 gifcontent_type = image/gif;if (strcmp(extension, jpg) = 0) (发送内容为 jpgcontent_type = image/jpg;read_from = fopen(arguments, r);/打开用户指定的文件准备读取if(read_from != NULL) (指针不为空char read_buf128;/读文件时的字节缓存数组send_header(sock, content_type); 发送协议头 send(sock, rn, 2, 0);/再加一个rn不能缺少格式要求while(!feof(read_from) (/判断文件是否已经结束fgets(read_buf, 128, read_from); /读取int len = strlen(read_buf);if (sendall(sock, read_buf, &len) = -1) ( /发送数据 printf(Sending error!);/出现发送错误显示到控制台继续发送continue; void handle_req(char* request, int client_sock) (char commandBUFSIZ;/保存解析到的命令字段GET PUTchar argumentsBUFSIZ;保存解析到的请求的文件strcpy(arguments, ./);/注意该符号在不同操作系统的区别if (sscanf(request, %s%s, command, arguments+2) != 2) ( return;解析出错在返回printf(handle_cmd:%sn,command);/向控制台输出此时的命令printf(handle_path: %sn,arguments);向控制台输出此时的请求路径if (strcmp(command, GET) != 0) (请求命令格式是否正确wrong_req(client_sock); return;if (not_exit(arguments) (/请求的文件是否存在file_not_found(arguments, client_sock);return;send_file(arguments, client_sock);/命令格式及请求路径正确则发送数据return;int make_server_socket() (struct sockaddr_in server_addr;/服务器地址结构体int tempSockId;临时存储socket描述符tempSockId = socket(PF_INET, SOCK_STREAM, 0);if (tempSockId = -1) (/如果返回值为一1则出错return -1;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);server_addr.sin_addr.s_addr = inet_addr(127.0.0.1); 本地地址 memset(&(server_addr.sin_zero), 0, 8);if (bind(tempSockId, (struct sockaddr *)&server_addr, sizeof(server_addr) = -1) (绑定服务如果出错则返回一 1printf(bind error!n); return -1;if (listen(tempSockId, BACKLOG) = -1 ) (开始监听printf(listen error!n); return -1;return tempSockId;/返回取得的 SOCKETvoid main(int argc, char * argv) (WSADATA wsaData;if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) ( fprintf(stderr, WSAStartup failed.n); exit(1);printf(My web server started.n);int server_socket;/服务器的 socketint acc_socket;/接收到的用户连接的socketint sock_size = sizeof(struct sockaddr_in);struct sockaddr_in user_socket;客户连接信息server_socket = make_server_socket();/创建服务器端的 socketif (server_socket = -1) (/创建 socket 出错printf(Server exception!、/);exit(2);while(true) (acc_socket = accept(server_socket, (struct sockaddr *)&user_socket,&sock_size); /接收连接/cout inet_ntoa(user_socket.sin_addr) endl; 测试用:-)/int numbytes;char buf100;if (numbytes二recv(acc_socket, buf, 99, 0) = -1) ( perror(recv);exit(1);/printf(buf . %s”, buf);/测试用handle_req(buf, acc_socket);和我的上一篇文章是一起写的,呵呵,大家给提点意见啊。:-)#include #include #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;返回取得的 SOCKETint 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=T?T:0;/成功发送返回0失败一1void main() (WSADATA wsaData;if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) ( fprintf(stderr, WSAStartup failed.n); exit(1);char server100;/用来保存用户想要连接的服务器地址char command100;用户命令char filename100;/用户输入的用来保存实体内容的文件名char bufMAXSIZE;读取数据的缓存字节数组FILE * to_store;用来存储文件内容的文件指针int len = -1;struct sockaddr_in remote_server;/远程服务器的连接信息struct hostent * host_info;/远程服务器的地址信息while(true) (int mysocket = make_socket(); /构建本地 socketcout 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* 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 temp1;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 (buf0 = r | buf0 = n) ( /出现两个rn 时 i=4 i+; else (i = 0;printf(%c”, buf0);/把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);
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸设计 > 毕设全套


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!