我正在编写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();
答案 0 :(得分:3)
只需使用setsockopt()
和SO_RCVTIMEO
设置读取超时,并在
read()
失败
errno == EAGAIN/EWOULDBLOCK
发送408。