Chinaunix

标题: Linux & C++ 编程问题 [打印本页]

作者: hj2ct    时间: 2005-02-08 13:18
标题: Linux & C++ 编程问题
小弟有一读本科的小朋友,要求编写如下程序。哪位朋友能指点一二。小弟我是学电子的,对操作系统以及网络编程不太精通,朋友又很急,时间紧迫。祝大家新年快乐

Involves designing and implementing a Web server program that can understand (part of) HTTP/1.1 and can return pages to a real client like netscape or explorer. A more detailed summary of the minimal functional requirements of the server:

1. it will be in C++ running on a Unix system,

2. you do not need to use classes in the C++ that you write,

3. it will return pages to a real WWW client,

4. it will use its own PORT number, not 80,

5. it will use a sub-directory to keep its own Web pages,

6. it will be a concurrent server able to process more than one request in parallel using processes not threads. You can base the main server loop on the program: echo_server_procs1.cpp  in the chapter on Network Programming in the Systems and Networks 2 course notes booklet

7. all socket I/O should use system calls (not  iostreamor studio library calls), however error messages and log file writing can use library calls. Reading files can be done with iostream calls or system calls and will depend on which is easier.

8. it only needs to deal with GET, HEAD and the OPTIONS requests,
(NB. only implement the * variant of OPTIONS ; your server's response should include a list of the commands it implements),

9. it must provide correct protocol response messages (as well as any HTML needed) for the following situations:
 correct requests and the file exists send the 200 "OK" response,
 if the command is either GET or HEAD but the requested resource (file) doesn't exist then it must send a 404 response.
 if the command is not recognised, ie not a legal HTTP/1.1 request it should return a 400 "Bad request" response,
 if the command is legal but not implemented by you, ie it is not GET, HEAD or OPTIONS then it should send a 501 "Not implemented" response,

10. it will use a log file to record all transactions

11. in addition to the first, primary response line it should return an additional line containing the Content-Type:. You can usually determine the content type by examining the extension of the name of the requested file. It should correctly identify the extensions: .htm .html .jpg .jpeg .txt
for .jpg or .jpeg it should return Content-Type: image/jpeg, for .txt it should return Content-Type: text/plain, and for .htm .html or any other extension it should return Content-Type: text/html

12. an extra task that might be harder to implement: it must only accept HTTP/1.1 requests if there is a Host: line in the request. If the protocol version in the request is HTTP/1.1 and there is no Host: line it should send a 400 "Bad request" response.

13. another extra task that might be harder to implement: if the file name in a GET request has the extension .php then you should execute the PHP interpreter giving the named file as argument and arranging for the standard output of the PHP interpreter to be redirected to the socket,

14. yet another extra task that might, or might not, be harder to implement: if the client request contains the option: Connection: keep-alive then the child process servicing the connection should be prepared to read further requests from the socket. Read RFC2616 for a fuller description of "keep-alive"
作者: hj2ct    时间: 2005-02-08 13:29
标题: Linux & C++ 编程问题
echo_server_procs1.cpp

#include <sys/types.h>;
#include <sys/socket.h>;
#include <netinet/in.h>;
#include <arpa/inet.h>;
#include <netdb.h>;
#include <iostream>;
#include <unistd.h>;
#include <stdlib.h>;
#include <signal.h>;
using namespace std;

int main(int argc, char *argv[]){
    int sock, newsock, stat, pid, rc;
    unsigned int cliaddrlen;
    struct sockaddr_in myaddr, cliaddr;
    struct hostent *hostptr;
    char buffer[2048], ip[64];
   
    if(argc != 2) {
        cerr << "usage: echo-server port-num\n"; exit(1);
    }
    cout << "TCP echo server (concurrent using processes)\n";

    signal(SIGCHLD,SIG_IGN);

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0) { cerr << "cant open socket\n"; exit(1);}
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    myaddr.sin_port = htons(atoi(argv[1]));

    stat = bind(sock, (struct sockaddr *) &myaddr, sizeof(myaddr));
    if(stat < 0) { cerr << "cant bind\n"; exit(1);}
   
    listen(sock,5); // make ready for accept
    cerr << "ready to accept connections\n";
    while(true) {
    cliaddrlen = sizeof(struct sockaddr_in);
    newsock=accept(sock,(struct sockaddr *) &cliaddr,&cliaddrlen);
    if(newsock < 0) { cerr << "accept error\n"; exit(1);}

    hostptr = gethostbyaddr((char *)&cliaddr.sin_addr,
                sizeof(struct in_addr),AF_INET);
    if(hostptr != 0)
            cerr << "connection from: " << hostptr->;h_name << "\n";
        else if(inet_ntop(AF_INET,&cliaddr.sin_addr,ip,64)!=0)
            cerr << "connection from: " << ip << "\n";
        else
            cerr << "cannot find IP address\n";

        pid = fork();
        if(pid < 0) { cerr << "fork failed\n"; }
        else if(pid == 0) { // new child clone process
            close(sock);
            rc = read(newsock,buffer,204;
            while(rc >; 0) {
                write(newsock,buffer,rc);
                rc = read(newsock,buffer,204;
            }
            close(newsock);
            exit(0);
        }
        // parent, close our copy of newsock and loop
        close(newsock);
    }
}




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2