Я написал программу сокета в C. Я использовал эту программу в качестве сервера чата/клиента, использующего TCP. Я попытался изменить сервер чата, чтобы использовать его в качестве HTTP-сервера, изменив порт на 80. Я ссылался на формат запроса/ответа HTTP в http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Example_session и заставлял мою программу отвечать с ответом на образец. Я пробовал URL-адресКак отформатировать ответ HTTP
http://127.0.0.1/
в браузере. Моя программа прочитала запрос и ответила с ответом. Сначала я использовал google-хром. Chrome не загружал страницу правильно, пока я не добавил правильную длину данных в заголовок Content-Length. После установки заголовка длины содержимого хром загрузил страницу правильно. Но Firefox не загружает страницу. Firefox не показывает никаких ошибок, но все равно загружает страницу, как будто она все еще ждет некоторых данных. Только Когда я останавливаю сервер или закрываю сокет, загружается полная страница. Я попытался выполнить rfc2616 http://tools.ietf.org/html/rfc2616 и сделал ответ точно, но результаты все же.
Запрос:
GET/HTTP/1.1 \ г \ nHost: 127.0.0.1:8080\r\nUser-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; с.в.: 33,0) Геккон/20100101 Firefox/33.0 \ г \ nAccept: текст/HTML, приложение/XHTML + XML, приложение/XML; д = 0,9, /; д = 0,8 \ г \ nAccept-Язык: ан-США, ен; д = 0,5 \ г \ nAccept-Encoding: GZIP, выкачать \ г \ nConnection: поддержания активности \ г \ п \ г \ п
Для вышеуказанного запроса моя программа записывается в сокет со следующим ответом &.
Ответ:
HTTP/1.1 200 OK \ г \ nCache-Control: нет кэша, частное \ г \ nContent-Length : 107 \ г \ nDate: пн, 24 ноября 2014 10: 21:21 GMT \ г \ п \ г \ п
Содержание:
<html><head><title></title></head><body>TIME : 1416824843 <br>DATE: Mon Nov 24 15:57:23 2014 </body></html>
Этот ответ загружается в Chrome, но не в Firefox. Chrome мгновенно загружает страницу, а firefox ждет данных. Обратите внимание, что длина 107 данных указана в заголовке. У меня нет никаких аддонов в firefox. Моя версия firefox находится в запросе. Версия Chrome: версия 38.0.2125.111 (64-разрядная версия).
Код:
void *socket_read(void *args)
{
int socket,*s,length;
char buf[1024];
s=(int *)args;
socket=*s;
while(1){
buf[0]='\0';
length=read(socket,buf,1024);
if(length==0)
break;
else if(length==-1){
perror("Read");
return;
}
else{
printf("Request: %s\n",buf);
send_response(socket);
}
}
printf("End of read thread [%d]\n",socket);
}
int start_accept(int port)
{
int socket,csocket;
pthread_t thread;
struct sockaddr_in client;
socklen_t addrlen=sizeof(client);
pthread_attr_t attr;
socket=create_socket(port);
while(1){
if((csocket=accept(socket,(struct sockaddr *)&client,&addrlen))==-1)
{
perror("Accept");
break;
}
pthread_attr_init(&attr);
if(0!=pthread_create(&thread,&attr,socket_read,&csocket))
{
perror("Read thread");
return;
}
usleep(10000);
}
}
void send_response(int socket)
{
char buf1[1024];
int content_length;
char buf2[1024]="<html><head><title></title></head><body>TIME : 1416824843 <br>DATE: Mon Nov 24 15:57:23 2014 </body></html>";
content_length=strlen(buf2);
sprintf(buf1,"HTTP/1.1 200 OK\r\nCache-Control : no-cache, private\r\nContent-Length : %d\r\nDate : Mon, 24 Nov 2014 12:03:43 GMT\r\n\r\n",content_length);
printf("Written: %d \n",write(socket,buf1,strlen(buf1)));
fflush(stdout);
printf("Written: %d \n",write(socket,buf2,content_length));
fflush(stdout);
}
Вы хотите создать постоянное соединение? Вы уверены, что все байты отправлены? Что произойдет, если вы добавите заголовок 'Connection: close' и закроете соединение после отправки данных? – CodeCaster
@CodeCaster Я хочу создать постоянное соединение. Я проверил количество байтов, написанных с использованием возвращаемого значения метода write()/send(). Если я добавлю заголовок закрытия соединения, хром загрузит страницу и закрывает соединение сокета, но Firefox все равно загружает страницу и не закрывает сокет. – smartkid