赞
踩
Linux程序设计综合实践是我们软件工程专业必须经历的过程,是理论与实践相结合的重要方式,使我们在实践中了解Linux操作系统、在实践中巩固知识。实习是个人综合能力的检验,除了有一定的课本知识外,还需有一定的实践动手能力,操作能力。实习是对我们软件工程专业知识的一种检验,它让我们学到了很多在课堂上根本就学不到的知识,技能开阔视野,又能增长见识,为我们走向工作打下坚实的基础,也是我们走向工作岗位的第一步。为了将所学的专业理论知识运用与实践,在实践中结合理论加深对其认识和总结。将专业与实际接轨,逐步认识,体会,从而更好地将所学的运用到工作中去。接触操作系统,认识linux,学会C语言,学会向老师提问,学会团结协作。通过深入编写程序,了解Linux和操作系统的现状,可加深理解并巩固所学专业知识,进一步提高认识问题、分析问题、解决问题的能力,使一个软件工程专业的学生应在linux综合实践与设计中用所学知识解决现实中的一些问题,对所学专业理论和实践知识进行巩固,同时提高自学、独立开发和协作能力,为走向工作岗位奠定良好的基础。
综合实践的要求是: 一、要求学生在实习过程中认真学习技术知识,积极与指导老师和同学配合;二、在前期,按时到勤,认真学习。积极做好实习日志,能够理解当天的内容。对技术的理论知识要及时实践;三、在后期,积极与同学沟通,认真完成项目要求的内容。在这个过程中要与老师同学多做沟通,通过探讨项目的`解决方案以及进展。
完成一个简单Web服务器程序设计与实现,要求学习网络套接字编程,HTTP协议、web服务器等知识;设计一个简单Web服务器,提供静态网页浏览服务功能;Web服务器可以配置的参数有主目录、首页问价名、HTTP端口号等项。
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <string.h>
- #include <ctype.h>
- #include <arpa/inet.h>
- #include <errno.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <pthread.h>
-
- #define SERVER_PORT 80
- static int debug = 1;
-
- int get_line(int sock, char* buf, int size);
- void* do_http_request(void* client_sock);
- void do_http_response(int client_sock, const char* path);
- int headers(int client_sock, FILE* resource);
- void cat(int client_sock, FILE* resource);
- void not_found(int client_sock);//404
- void unimplemented(int client_sock);//500
- void bad_request(int client_sock); //400
- void inner_error(int client_sock);
- #include "hanshu.h"
-
- void* do_http_request(void* pclient_sock) {
- int len = 0;
- char buf[256];
- char method[64];
- char url[256];
- char path[256];
- int client_sock = *(int*)pclient_sock;
- struct stat st;
-
- //读取客户端发送的http请求
- len = get_line(client_sock, buf, sizeof(buf));
-
- if (len > 0) {
- int i = 0, j = 0;
- while (!isspace(buf[j]) && (i < sizeof(method) - 1)) {
- method[i] = buf[j];
- i++;
- j++;
- }
-
- method[i] = '\0';
- if (debug) printf("request method: %s\n", method);
-
- if (strncasecmp(method, "GET", i) == 0) { //处理get请求
- if (debug) printf("method = GET\n");
-
- //获取url
- while (isspace(buf[j++]));
- i = 0;
- while (!isspace(buf[j]) && (i < sizeof(url) - 1)) {
- url[i] = buf[j];
- i++;
- j++;
- }
- url[i] = '\0';
- if (debug) printf("url: %s\n", url);
- do {
- len = get_line(client_sock, buf, sizeof(buf));
- if (debug) printf("read: %s\n", buf);
-
- } while (len > 0);
- //处理url中的?
- {
- char* pos = strchr(url, '?');
- if (pos) {
- *pos = '\0';
- printf("real url: %s\n", url);
- }
- }
- sprintf(path, "./html_docs/%s", url); // html_doc 网页目录
- if (debug) printf("path: %s\n", path);
-
- //判断文件是否存在,如果不存在,就响应 404 NOT FOUND.
- if (stat(path, &st) == -1) {//文件不存在或是出错
- fprintf(stderr, "stat %s failed. reason: %s\n", path, strerror(errno));
- not_found(client_sock);
- }
- else {//文件存在
-
- if (S_ISDIR(st.st_mode)) {
- strcat(path, "/index.html");// 如果是ip地址,则添加主页路径
- }
- do_http_response(client_sock, path);
- }
- }
- else {//非get请求响应客户端 501 Method Not Implemented
- fprintf(stderr, "warning! other request [%s]\n", method);
- do {
- len = get_line(client_sock, buf, sizeof(buf));
- if (debug) printf("read: %s\n", buf);
-
- } while (len > 0);
-
- unimplemented(client_sock); //请求未实现
-
- }
- }
- else {//请求格式有问题,出错处理
- bad_request(client_sock); //在响应时再实现
- }
- close(client_sock);
- if (pclient_sock) free(pclient_sock);//释放动态分配的内存
- return NULL;
- }
-
- void do_http_response(int client_sock, const char* path) {
- int ret = 0;
- FILE* resource = NULL;
-
- resource = fopen(path, "r");
-
- if (resource == NULL) {
- not_found(client_sock);
- return;
- }
-
- //1.发送http 头部
- ret = headers(client_sock, resource);
-
- //2.发送http body .
- if (!ret) {
- cat(client_sock, resource);
- }
- fclose(resource);
- }
- #include "hanshu.h"
-
- // 响应文件的头部
- int headers(int client_sock, FILE* resource) {
- struct stat st;
- int fileid = 0;
- char tmp[64];
- char buf[1024] = { 0 };
- strcpy(buf, "HTTP/1.0 200 OK\r\n");
- strcat(buf, "Server: Martin Server\r\n");
- strcat(buf, "Content-Type: text/html\r\n");
- strcat(buf, "Connection: Close\r\n");
-
- fileid = fileno(resource);
-
- if (fstat(fileid, &st) == -1) {
- inner_error(client_sock);
- return -1;
- }
-
- snprintf(tmp, 64, "Content-Length: %ld\r\n\r\n", st.st_size);
- strcat(buf, tmp);
- if (debug) fprintf(stdout, "header: %s\n", buf);
- if (send(client_sock, buf, strlen(buf), 0) < 0) {
- fprintf(stderr, "send failed. data: %s, reason: %s\n", buf, strerror(errno));
- return -1;
- }
- return 0;
- }
-
- // 读取内容,发送给客户端
- void cat(int client_sock, FILE* resource) {
- char buf[1024];
-
- fgets(buf, sizeof(buf), resource);
-
- while (!feof(resource)) {
- int len = write(client_sock, buf, strlen(buf));
-
- if (len < 0) {//发送body 的过程中出现问题,怎么办?1.重试? 2.
- fprintf(stderr, "send body error. reason: %s\n", strerror(errno));
- break;
- }
-
- if (debug) fprintf(stdout, "%s", buf);
- fgets(buf, sizeof(buf), resource);
-
- }
- }
-
-
- //返回值: -1 表示读取出错, 等于0表示读到一个空行, 大于0 表示成功读取一行
- int get_line(int sock, char* buf, int size) {
- int count = 0;
- char ch = '\0';
- int len = 0;
-
- while ((count < size - 1) && ch != '\n') {
- len = read(sock, &ch, 1);
-
- if (len == 1) {
- if (ch == '\r') {
- continue;
- }
- else if (ch == '\n') {
- break;
- }
- //处理一般的字符
- buf[count] = ch;
- count++;
- }
- else if (len == -1) {//读取出错
- perror("read failed");
- count = -1;
- break;
- }
- else {// read 返回0,客户端关闭sock 连接.
- fprintf(stderr, "client close.\n");
- count = -1;
- break;
- }
- }
- if (count >= 0) buf[count] = '\0';
- return count;
- }
-
-
- void not_found(int client_sock) {
- const char* reply = "HTTP/1.0 404 NOT FOUND\r\n\
- Content-Type: text/html\r\n\
- \r\n\
- <HTML lang=\"zh-CN\">\r\n\
- <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\r\n\
- <HEAD>\r\n\
- <TITLE>NOT FOUND</TITLE>\r\n\
- </HEAD>\r\n\
- <BODY>\r\n\
- <P>文件不存在!\r\n\
- <P>The server could not fulfill your request because the resource specified is unavailable or nonexistent.\r\n\
- </BODY>\r\n\
- </HTML>";
-
- int len = write(client_sock, reply, strlen(reply));
- if (debug) fprintf(stdout, reply);
-
- if (len <= 0) {
- fprintf(stderr, "send reply failed. reason: %s\n", strerror(errno));
- }
-
-
- }
-
- void unimplemented(int client_sock) {
- const char* reply = "HTTP/1.0 501 Method Not Implemented\r\n\
- Content-Type: text/html\r\n\
- \r\n\
- <HTML>\r\n\
- <HEAD>\r\n\
- <TITLE>Method Not Implemented</TITLE>\r\n\
- </HEAD>\r\n\
- <BODY>\r\n\
- <P>HTTP request method not supported.\r\n\
- </BODY>\r\n\
- </HTML>";
-
- int len = write(client_sock, reply, strlen(reply));
- if (debug) fprintf(stdout, reply);
-
- if (len <= 0) {
- fprintf(stderr, "send reply failed. reason: %s\n", strerror(errno));
- }
- }
-
- void bad_request(int client_sock) {
- const char* reply = "HTTP/1.0 400 BAD REQUEST\r\n\
- Content-Type: text/html\r\n\
- \r\n\
- <HTML>\r\n\
- <HEAD>\r\n\
- <TITLE>BAD REQUEST</TITLE>\r\n\
- </HEAD>\r\n\
- <BODY>\r\n\
- <P>Your browser sent a bad request!\r\n\
- </BODY>\r\n\
- </HTML>";
-
- int len = write(client_sock, reply, strlen(reply));
- if (len <= 0) {
- fprintf(stderr, "send reply failed. reason: %s\n", strerror(errno));
- }
- }
-
-
- void inner_error(int client_sock) {
- const char* reply = "HTTP/1.0 500 Internal Sever Error\r\n\
- Content-Type: text/html\r\n\
- \r\n\
- <HTML lang=\"zh-CN\">\r\n\
- <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\r\n\
- <HEAD>\r\n\
- <TITLE>Inner Error</TITLE>\r\n\
- </HEAD>\r\n\
- <BODY>\r\n\
- <P>服务器内部出错.\r\n\
- </BODY>\r\n\
- </HTML>";
-
- int len = write(client_sock, reply, strlen(reply));
- if (debug) fprintf(stdout, reply);
-
- if (len <= 0) {
- fprintf(stderr, "send reply failed. reason: %s\n", strerror(errno));
- }
-
-
- }
- #include "hanshu.h"
-
- int main(void) {
-
- int sock;
- struct sockaddr_in server_addr;
-
- sock = socket(AF_INET, SOCK_STREAM, 0);
- bzero(&server_addr, sizeof(server_addr));
-
- server_addr.sin_family = AF_INET;//IPV4
- server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//监听本地所有IP地址
- server_addr.sin_port = htons(SERVER_PORT);//绑定端口号
-
- bind(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
- listen(sock, 128);
- printf("等待客户端的连接\n");
-
- int done = 1;
- while (done) {
- struct sockaddr_in client;
- int client_sock, len, i;
- char client_ip[64];
- char buf[256];
- pthread_t id;
- int* pclient_sock = NULL;
-
- socklen_t client_addr_len;
- client_addr_len = sizeof(client);
- client_sock = accept(sock, (struct sockaddr*)&client, &client_addr_len);
-
- //打印客户端IP地址和端口号
- printf("client ip: %s\t port : %d\n",inet_ntop(AF_INET, &client.sin_addr.s_addr, client_ip, sizeof(client_ip)),ntohs(client.sin_port));
-
- //启动线程处理http请求
- pclient_sock = (int*)malloc(sizeof(int));
- *pclient_sock = client_sock;
-
- pthread_create(&id, NULL, do_http_request, (void*)pclient_sock);
- }
- close(sock);
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。