sma*_*kid 3 sockets firefox network-programming google-chrome http
我用 C 编写了一个套接字程序。我使用这个程序作为使用 TCP 的聊天服务器/客户端。我试图通过将端口更改为 80 来更改聊天服务器以将其用作 HTTP 服务器。我参考了http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Example_session 中的 HTTP 请求/响应格式,并制作了我的程序以示例响应进行回复。我试过网址
http://127.0.0.1/
Run Code Online (Sandbox Code Playgroud)
在浏览器中。我的程序读取请求并回复响应。起初,我使用谷歌浏览器。Chrome 没有正确加载页面,直到我在 Content-Length 标头中添加了正确的数据长度。设置内容长度标题后,chrome 正确加载了页面。但是,firefox 不会加载页面。Firefox 没有显示任何错误,但仍在加载页面,就像仍在等待一些数据一样。只有当我停止服务器或关闭套接字时,才会加载完整的页面。我尝试按照 rfc2616 http://tools.ietf.org/html/rfc2616 进行操作,并准确做出响应,但结果仍然相同。
要求:
GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nUser-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0\r\nAccept: text/ html,application/xhtml+xml,application/xml;q=0.9, / ;q=0.8\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\ n连接:保持活动\r\n\r\n
对于上述请求,我的程序使用以下响应和内容写入套接字。
回复:
HTTP/1.1 200 OK\r\n缓存控制:无缓存,私有\r\n内容长度:107\r\n日期:2014 年 11 月 24 日星期一 10:21:21 GMT\r\n\r\n
内容:
<html><head><title></title></head><body>TIME : 1416824843 <br>DATE: Mon Nov 24 15:57:23 2014 </body></html>
Run Code Online (Sandbox Code Playgroud)
此响应正在 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);
}
Run Code Online (Sandbox Code Playgroud)
我找到了问题所在。响应不正确。标题字段名称和冒号(':')之间不应有任何空格。在http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 中找到了这个。
我的正确答案是
HTTP/1.1 200 OK\r\nCache-Control: no-cache, private\r\nContent-Length: 107\r\nDate: Mon, 24 Nov 2014 10:21:21 GMT\r\n\r\n
Run Code Online (Sandbox Code Playgroud)
我在 'Content-Length' 和 ':' 之间加了一个空格。这就是 Firefox 忽略内容长度标头并读取套接字的原因。Chrome 接受带有空格的标题字段,因此该问题不会出现在 chrome 中。
删除空间后,程序工作正常。
归档时间: |
|
查看次数: |
12385 次 |
最近记录: |