这个版本还不是很完善,但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;
- }
-
-
-
-
- void wrong_req(int sock) {
- char* error_head = "HTTP/1.0 501 Not Implemented\r\n";
- int len = strlen(error_head);
- if (sendall(sock, error_head, &len) == -1) {
- printf("Sending failed!");
- return;
- }
- char* error_type = "Content-type: text/plain\r\n";
- len = strlen(error_type);
- if (sendall(sock, error_type, &len) == -1) {
- printf("Sending failed!");
- return;
- }
- char* error_end = "\r\n";
- len = strlen(error_end);
- if (sendall(sock, error_end, &len) == -1) {
- printf("Sending failed!");
- return;
- }
- char* prompt_info = "The command is not yet completed\r\n";
- 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 Found\r\n";
- int len = strlen(error_head);
- if (sendall(sock, error_head, &len) == -1) {
- printf("Sending error!");
- return;
- }
- char* error_type = "Content-type: text/plain\r\n";
- len = strlen(error_type);
- if (sendall(sock, error_type, &len) == -1) {
- printf("Sending error!");
- return;
- }
- char* error_end = "\r\n";
- len = strlen(error_end);
- if (sendall(sock, error_end, &len) == -1) {
- printf("Sending error!");
- return;
- }
- char prompt_info[50] = "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 OK\r\n";
- int len = strlen(head);
- if (sendall(send_to, head, &len) == -1) {
- printf("Sending error");
- return;
- }
- if (content_type) {
- char temp_1[30] = "Content-type: ";
- strcat(temp_1, content_type);
- strcat(temp_1, "\r\n");
- 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";
- FILE* read_from;
- int readed = -1;
-
- if (strcmp(extension, "html") == 0) {
- content_type = "text/html";
- }
- if (strcmp(extension, "gif") == 0) {
- content_type = "image/gif";
- }
- if (strcmp(extension, "jpg") == 0) {
- content_type = "image/jpg";
- }
- read_from = fopen(arguments, "r");
- if(read_from != NULL) {
- char read_buf[128];
- send_header(sock, content_type);
- send(sock, "\r\n", 2, 0);
- 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 command[BUFSIZ];
- char arguments[BUFSIZ];
-
-
-
- strcpy(arguments, "./");
-
-
-
- if (sscanf(request, "%s%s", command, arguments+2) != 2) {
- return;
- }
-
- printf("handle_cmd: %s\n",command);
- printf("handle_path: %s\n",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;
- tempSockId = socket(PF_INET, SOCK_STREAM, 0);
-
- if (tempSockId == -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) {
- printf("bind error!\n");
- return -1;
- }
- if (listen(tempSockId, BACKLOG) == -1 ) {
- printf("listen error!\n");
- return -1;
- }
- return tempSockId;
- }
-
-
-
-
- void 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;
- int acc_socket;
- int sock_size = sizeof(struct sockaddr_in);
- struct sockaddr_in user_socket;
- server_socket = make_server_socket();
- if (server_socket == -1) {
- printf("Server exception!\n");
- exit(2);
- }
-
-
-
- while(true) {
- acc_socket = accept(server_socket, (struct sockaddr *)&user_socket, &sock_size);
-
-
-
-
-
-
- int numbytes;
- char buf[100];
- if ((numbytes=recv(acc_socket, buf, 99, 0)) == -1) {
- perror("recv");
- exit(1);
- }
-
-
-
-
-
- handle_req(buf, acc_socket);
- }
- }
-
阅读(2604) | 评论(0) | 转发(2) |