0

変。含まれているコードを使用して、ローカル マシンで GET 要求を行うことができます。これは魅力的な方法です。GET -Ue 192.168.2.106:8129I getを使用して、ローカル マシンのコマンド ラインから

200 OK
Content-Length: 296
Content-Type: text/html
Client-Date: Sat, 09 Feb 2013 20:26:09 GMT
Client-Response-Num: 1

<html><body><h1>Directory</h1><a href=/.>.</a><br/><a href=/..>..</a><br/><a href=/bldg.jpg>bldg.jpg</a><br/><a href=/hello.txt>hello.txt</a><br/><a href=/world.gif>world.gif</a><br/><a href=/index.html>index.html</a><br/><a href=/testing>testing</a><br/><a href=/favicon.ico>favicon.ico</a><br/>

私が得るリモートマシンから

200 OK
Content-Length: 328
Content-Type: text/html
Client-Aborted: die
Client-Date: Sat, 09 Feb 2013 20:25:16 GMT
Client-Response-Num: 1
X-Died: read failed: Connection reset by peer at /usr/share/perl5/LWP/Protocol/http.pm line 414.

2 番目のものは動作するように見えますが、不安定な "X-Died" ヘッダーは奇妙です。GetLine メソッドがオフになっているのではないかとこっそり疑っていますが、よくわかりません。この問題の原因は何ですか?

主な機能:

int main(int argc, char* argv[])
{
    // First set up the signal handler
    struct sigaction sigold, signew;

    signew.sa_handler = handler;
    sigemptyset(&signew.sa_mask);
    sigaddset(&signew.sa_mask, SIGPIPE);
    signew.sa_flags = SA_RESTART;
    sigaction(SIGPIPE, &signew, &sigold);

    int     hSocket,hServerSocket;  /* handle to socket */
    struct  hostent* pHostInfo;     /* holds info about a machine */
    struct  sockaddr_in Address;    /* Internet socket address stuct */
    int     nAddressSize=sizeof(struct sockaddr_in);
    char    pBuffer[BUFFER_SIZE];
    int     nHostPort;

    q = new myQueue();

    // THREAD POOL!
    pthread_t thread_id[NUMTHREADS];
    int i=0;
    for(i=0; i < NUMTHREADS; i++)
    {
        threadParams param;
        param.a = i;
        pthread_create(&thread_id[i], 0, &WorkerHandler, NULL);
    }

    if(argc < 2)
    {
        printf("\nUsage: server host-port\n");
        return 0;
    }
    else
    {
        nHostPort = atoi(argv[1]);
    }

    printf("\nStarting server");
    printf("\nMaking socket");

    /* make a socket */
    hServerSocket=socket(AF_INET,SOCK_STREAM,0);

    if(hServerSocket == SOCKET_ERROR)
    {
        printf("\nCould not make a socket\n");
        return 0;
    }

    /* fill address struct */
    Address.sin_addr.s_addr=INADDR_ANY;
    Address.sin_port=htons(nHostPort);
    Address.sin_family=AF_INET;

    printf("\nBinding to port %d",nHostPort);

    int optval = 1;
    setsockopt(hServerSocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

    /* bind to a port */
    if(bind(hServerSocket,(struct sockaddr*)&Address,sizeof(Address)) == SOCKET_ERROR)
    {
        printf("\nCould not connect to host\n");
        return 0;
    }

    /*  get port number */
    getsockname( hServerSocket, (struct sockaddr *) &Address,(socklen_t *)&nAddressSize);
    printf("opened socket as fd (%d) on port (%d) for stream i/o\n",hServerSocket, ntohs(Address.sin_port) );

    printf("Server\n\
             sin_family        = %d\n\
             sin_addr.s_addr   = %d\n\
             sin_port          = %d\n"
             , Address.sin_family
             , Address.sin_addr.s_addr
             , ntohs(Address.sin_port));

    /* establish listen queue */
    if(listen(hServerSocket, 1000) == SOCKET_ERROR)
    {
        printf("\nCould not listen\n");
        return 0;
    }

    while(1)
    {
        int socket = accept(hServerSocket, (struct sockaddr*)&Address, (socklen_t *)&nAddressSize);
        q->enqueue(socket);
    }
}

void handler (int status)
{
}

ソケットでリクエストを処理します。

int handleRequest(int socket)
{
    cout << "handling a request..." << endl;

    // Get the URL
    char * line = GetLine(socket);

    //char * line = "GET /bldg.jpg HTTP/1.1";
    char * url;
    url = strtok(line, " "); // Splits spaces between words in str
    url = strtok(NULL, " "); // Splits spaces between words in str

    // build filename
    ostringstream fullpathstream;
    fullpathstream << dirpath << url;
    string fullpath = fullpathstream.str();

    //Use the stat function to get the information
    struct stat fileAtt;
    if (stat(fullpath.c_str(), &fileAtt) != 0) //start will be 0 when it succeeds
    {
        cout << "File not found:" << fullpath.c_str() << endl;
        writeError(socket);
        return 0;
    }

    // Make correct filetypes
    if (S_ISREG (fileAtt.st_mode))
    {
        printf ("%s is a regular file.\n", fullpath.c_str());

        char * contentType;
        if(strstr(url, ".jpg"))
        {
            cout << "JPEG" << endl;
            contentType = "image/jpg";
        }
        else if(strstr(url, ".gif"))
        {
            contentType = "image/gif";
            cout << "GIF" << endl;
        }
        else if(strstr(url, ".html"))
        {
            contentType = "text/html";
            cout << "HTML" << endl;
        }
        else if(strstr(url, ".txt"))
        {
            cout << "TXT" << endl;
            contentType = "text/plain";
        }
        else if(strstr(url, ".ico"))
        {
            cout << "ICO" << endl;
            contentType = "image/ico";
        }
        serveFile(fullpath, socket, fileAtt.st_size, contentType);
    }

    if (S_ISDIR (fileAtt.st_mode))
    {
        printf ("%s is a directory.\n", fullpath.c_str());
        serveDirectory(socket, url);
    }

    return 0;
};

リクエストの最初の行を取得するための GetLine 関数を使用して、リクエストされた URL を知りました。

// Read the line one character at a time, looking for the CR
// You dont want to read too far, or you will mess up the content
char * GetLine(int fds)
{
   char tline[MAX_MSG_SZ];
   char *line;

   int messagesize = 0;
   int amtread = 0;
   while((amtread = read(fds, tline + messagesize, 1)) < MAX_MSG_SZ)
   {
       if (amtread > 0)
           messagesize += amtread;
       else
       {
           perror("Socket Error is:");
           fprintf(stderr, "Read Failed on file descriptor %d messagesize = %d\n", fds, messagesize);
           exit(2);
       }
       //fprintf(stderr,"%d[%c]", messagesize,message[messagesize-1]);
       if (tline[messagesize - 1] == '\n')
           break;
   }
   tline[messagesize] = '\0';
   chomp(tline);
   line = (char *)malloc((strlen(tline) + 1) * sizeof(char));
   strcpy(line, tline);
   //fprintf(stderr, "GetLine: [%s]\n", line);
   return line;
}

マルチスレッドが発生しており、ここでソケットを閉じます。

void * WorkerHandler(void *arg)
{
    threadParams* params = (threadParams*)arg;
    while(1)
    {
        int socket = q->dequeue();
        handleRequest(socket);
        if(close(socket) == SOCKET_ERROR)
        {
            printf("\nCould not close socket\n");
            return 0;
        }
    }
}
4

0 に答える 0