我正在编写一个将页面发送到浏览器时遇到问题的网络服务器。 它正确发送第一个文件(该文件包含两个css文件)。 但是,在发送第二个文件后,浏览器停止请求数据。 它总是错过完成页面所需的一个css文件。

这是一些交易:

GET / HTTP/1.1
Host: website.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko)               Chrome/26.0.1410.43 Safari/537.31
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

HTTP/1.1 OK 200
Server: thserver
Date: Mon Apr 15 17:29:51 2013
Content-Length: 564

Data received: GET /main.css HTTP/1.1
Host: website.com
Connection: keep-alive
Accept: text/css,*/*;q=0.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko)     Chrome/26.0.1410.43 Safari/537.31
Referer: http://website.com/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

HTTP/1.1 OK 200
Server: thserver
Date: Mon Apr 15 17:29:51 2013
Content-Length: 386

如果有人也知道验证http事务的好方法也会有所帮助。 我确实查看了chrome的开发工具并显示它正在等待接收最后一个文件,但我似乎从未在服务器上获得接收请求。

此外,我使用telnet模拟浏览器,它工作正常。 这是我输入的内容:

GET / 
GET /index.css
GET /main.css

它每次都会发回文件。

代码使用read(2)继续轮询套接字,但在第三个文件的请求到达时仍保持返回EAGAIN或EWOULDBLOCK。

这是socket io的代码:

const int port_number   = 80;
const int timeout       = 5000000;
const int wait_time     =   10000;

PORT_CALL {

    /* declarations here */

    read_client:

    result = read( socket[ 0 ], &header_buffer[ bytes_read ], BUFFER_SIZE - bytes_read );

    if( result < 0 ){
        if( errno & ( EWOULDBLOCK | EAGAIN ) ){

            if( bytes_read > 0 ){

                bytes_read = 0;
                read_timeout = 0;
                goto respond_request;
            }
            if( read_timeout < timeout ){
                read_timeout += wait_time;
                usleep( wait_time );
                goto read_client;
            }
        }
        goto exit_thread;

    } else if( result > -1 ){
        bytes_read += result;
        goto read_client;
    }
    respond_request:

    /* respond stuff start */

    /* respond stuff end */

    goto read_client;

    exit_thread:

这是涉及创建套接字的代码

temp->socket_descriptor = socket( AF_INET, SOCK_STREAM, 0 );

temp->server_address.sin_family = AF_INET;
temp->server_address.sin_addr.s_addr = INADDR_ANY;
temp->server_address.sin_port = htons( * temp->port_number );

if( bind( temp->socket_descriptor,
          ( struct sockaddr * ) &temp->server_address,
          sizeof( temp->server_address ) ) < 0 ) ..

listen( temp->socket_descriptor, 10 );

wait_for_client:

new_socket = accept( temp->socket_descriptor,
                     ( struct sockaddr * ) &client_address,
                     &address_length );

我知道我可能会问太多。 如果有人知道一个好的调试工具,我可能会想到这一点,我也非常感谢。 如果有人建议一个帮助我解决问题的调试工具,我也会认为这是一个答案。

编辑:写入和读取功能现在处于循环中,但问题仍然存在。

===============>>#1 票数:2 已采纳

如果您只是学习如何使用数据包捕获进行调试,那么wireshark可能更容易入手。 它提供了一个GUI,可以轻松定义简单的规则并直观地检查捕获。 这当然是品味问题,所以只是一个建议。

至于代码,很难说出问题可能是什么,因为它不是SSCCE 我有一些建议,

  1. 如果你要检查if( filename )类的东西,那么filename = NULL; 你释放后。
  2. 如果你想将缓冲区归零,请将其设置为memset或循环整个大小。 for( ; header_buffer[ i ]; i++ ) header_buffer[ i ] = 0; 看起来危险。
  3. 除了<0之外,准备从返回0的套接字读取和写入。
  4. 你的写作是循环的。

你的读循环是在它有完整的请求之前,还是直到它有更多的0字节? 看起来像后者,那是对的。

编辑,添加下面的文字:示例中的代码仍然不是很完整(写入fex在哪里?),因此很难猜出确切的问题。 然而,有一些相当致命的缺陷。

  1. if( errno & ( EWOULDBLOCK | EAGAIN ) ) ,不应该像当前那样测试errno。 在Linux上,您可以测试(errno == EWOULDBLOCK),因为EAGAIN和EWOULDBLOCK是相同的。 在它们不同的系统上,使用两个带||的测试 它们之间。 如果errno是fex ECONNRESET,则当前代码返回非零(在Linux上)。

  2. 现在代码在技术上涵盖了返回0的读取,但不是特殊情况。 读取返回0表示连接正在关闭,您不应再读取套接字。

关于Web服务器中可能存在的问题的一个疯狂猜测(与上面的#2相关)是客户端在接收第三个文件之前断开连接并且服务器在关闭的套接字上保持忙碌循环。

我建议浏览Beejs指南或一些关于系统和套接字编程的书。

  ask by community wiki translate from so

未解决问题?本站智能推荐:

2回复

子域和套接字

我正在尝试编写一个简单的应用程序以在网站上发出http get请求。 然后会将一些值放入数据库中。 但是即时消息已经停留在一开始。 我试图访问一个子域(不确定那是否叫它),然后向它写入一个get命令。 但是我似乎无法连接到该网站,因为我获得的IP显然是来自主站点。 最终我想要执行以
1回复

服务器套接字errno 57-套接字未连接

由于某种原因,我遇到错误57-套接字未连接。 为什么? 控制台输出: 编码:
2回复

c通过套接字发送图像

我正在制作一个简单的http服务器。 到目前为止套接字适用于html文件,现在我正在尝试制作工作图像。 这就是我读文件的方式: 然后我只是将数据发送到套接字: 为什么它不适用于图像? 浏览器显示错误The image “http://127.0.0.1:1050/ima
1回复

套接字http请求失败

我正在编写简单的C程序以将http请求发送到已加载的USB调制解调器设备(cdc_ether),其IP地址为192.168.0.144,并且在ubuntu计算机上具有ethx接口。我能够成功发送请求http请求失败。 由于设备使用http进行控制,因此请求进行控制管理。 定义BUFFSI
2回复

使用C在套接字编程中获取请求的地址

我正在使用这样的东西来创建一个使用C的服务器。当我从浏览器转到127.0.0.1:5000 ,我可以看到"Hello Worlds"因为我将它作为缓冲区发送。 但我希望127.0.0.1:5000/filename.html能够正常工作。 但是我不知道如何在C中以127.0.0.1:5000
2回复

在C中使用套接字的HTTP请求

所以。 我正在尝试创建一个从服务器检索.html文件的C应用程序,例如www.example.com 。 为此,我使用套接字并connect send和recv方法。 我的实现看起来像这样: 但问题是它会在recv停留几秒钟,然后缓冲区buf被填充: 显然,服务器永远不会得
1回复

C套接字:recv(...)没有返回正确的字节

如果我telnet到telnet www.xlhi.com 80 ,并应用以下GET请求: 我收到以下回复: 一切都很好,正如预期的那样。 我对返回的gzip二进制数据感兴趣(“Hello”)。 现在,我有这个C函数,它将GET请求应用于服务器(在本例中为www.xlhi
1回复

http套接字请求返回尾随字符

我正在学习C语言中的网络编程,并尝试创建玩具版本的wget。 但是,当我运行程序时,在页面的开头和结尾都带有一些尾随字符(在这种情况下为0&f43)。 该程序包含两个.c和两个.h文件。 一个用于解析(天真的)地址,另一个用于发出网络请求并转储数据。 以下是用于解析输入的
1回复

使用C用套接字编程负载均衡器

我正在尝试为3个HTTP服务器{hosts =“ web1”,“ web2”,“ web3”} {负载均衡器端口=“ 8081”,“ 8082”,“ 8083”}做一个负载均衡器。 该负载平衡器将HTTP请求随机传输到其中一台服务器,然后将请求结果返回给发送方。 我从套接字开始,所以
1回复

用C连接到远程主机(套接字编程)

我的问题很简单:我想从服务器发出HTTP GET请求。 我的客户端程序获取一个URL并将其发送到服务器程序。 我想知道如何使用此URL并针对从客户端输入的特定页面发出HTTP GET请求。 如果我解析URL以获得IP地址,则可以打开该IP地址的套接字,但是我将如何请求实际页面呢? 我