如何为我的HTTP服务器指定请求超时?

时间:2014-11-22 16:34:56

标签: c sockets http network-programming

我正在编写HTTP服务器,我想为它实现408响应状态代码

此状态代码用于“请求超时”,我不知道应该如何以及何时发送此响应。

这是来自RFC的此状态代码的定义: 服务器超时等待请求。根据HTTP规范:“客户端在服务器准备等待的时间内没有产生请求。客户端可以在以后不经修改的情况下重复请求。”

服务器总是循环并接受我不知道如何计算请求时间的连接,然后在发送请求的时间达到某个阈值时发送响应。

这是我的代码:

int sock, connected, bytes_recieved , _true = 1 , portNumber;
char send_data [1024] , recv_data[1024];      
struct sockaddr_in server_addr,client_addr;   
int sin_size;

 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
    perror("Unable to create the Socket");
    exit(1);
}
  if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&_true,sizeof(int)) == -1) {
    perror("Unable to Setsockopt");
    exit(1);
}
char *server_address="127.1.1.1";
portNumber=8080;
 server_addr.sin_family = AF_INET; 
////htons function makes sure that numbers are stored in memory in network byte order (big indian)
server_addr.sin_port = htons(portNumber);
server_addr.sin_addr.s_addr = inet_addr("127.1.1.1");//inet_pton(AF_INET,"127.0.0.1",&server_addr.sin_addr);//INADDR_ANY;

//save the host information for future purposes
string host=server_address+':'+to_string(portNumber);

//bzero(&(server_addr.sin_zero),8); --This is for POSIX based systems

memset(&(server_addr.sin_zero),0,8);//sockaddr_in zero padding is needed
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))==-1) //bind the socket to a local address
{
    perror("Unable to bind");
    exit(1);
}

if (listen(sock, 5) == -1) //listen to the socket with the specified waiting queue size
{
    perror(" Listen");
    exit(1);
}

cout << "MyHTTPServer waiting on port 8080" << endl;
fflush(stdout);

sin_size = sizeof(struct sockaddr_in);
connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size);

cout<< "I got a connection from (" << inet_ntoa(client_addr.sin_addr) << "," << ntohs(client_addr.sin_port) << ')' << endl;
//fflush(stdout);
    char sendBuffer[500];
FILE *sendFile = fopen("foo.html", "r");
fseek(sendFile, 0L, SEEK_END);
int sz = ftell(sendFile);
fseek(sendFile, 0L, SEEK_SET);

char receiveBuffer[400];
recv(connected,receiveBuffer,sizeof(receiveBuffer),0);
cout << "Received:\n" << receiveBuffer << endl;

string s1;
s1="HTTP/1.1 200 OK\nContent-length: " + to_string(sz) + "\n";
std::vector<char> writable(s1.begin(), s1.end());
writable.push_back('\0');

//"HTTP/1.1 200 OK\nContent-length: 222\n"
strcpy(sendBuffer,(const char *)&writable[0]);
int c=send(connected,(const char*)&sendBuffer,strlen(&writable[0]),0);
printf("\nSent : %s\n",sendBuffer);
strcpy(sendBuffer,"Content-Type: text/html\n\n");
c=send(connected,(const char*)&sendBuffer,strlen("Content-Type: text/html\n\n"),0);
printf("\nSent : %s\n",sendBuffer);
    char send_buffer[500];


while( true )
{
    if(feof(sendFile))
    {
        break;
    }
    int numread = fread(send_buffer, sizeof(unsigned char), sz, sendFile);
    if( numread < 1 ) break; // EOF or error

    char *send_buffer_ptr = send_buffer;
    do
    {
        int numsent = send(connected,send_buffer_ptr, numread, 0);
        if( numsent < 1 ) // 0 if disconnected, otherwise error
        {
            if( numsent < 0 )
            {
                if( WSAGetLastError() == WSAEWOULDBLOCK )
                {
                    fd_set wfd;
                    FD_ZERO(&wfd);
                    FD_SET(connected, &wfd);

                    timeval tm;
                    tm.tv_sec = 10;
                    tm.tv_usec = 0;

                    if( select(0, NULL, &wfd, NULL, &tm) > 0 )
                        continue;
                }
            }

            break; // timeout or error
        }

        send_buffer_ptr += numsent;
        numread -= numsent;
        cout << "round";
    }
    while( numread > 0 );
}

//printf("\nSTATUS:%d",c);

WSACleanup();

1 个答案:

答案 0 :(得分:3)

只需使用setsockopt()SO_RCVTIMEO设置读取超时,并在

时出现read()失败
errno == EAGAIN/EWOULDBLOCK

发送408。