goahead上传文件的问题

以前针对goahead研究过如何使用cookie,如今在使用它进行上传文件时又出现了一点问题,首先,之前goahead在原来的板子跑的时候,上传文件一直正常,使用的mips交叉编译。现在使用arm交叉编译,虽然优化的比较厉害,但是其余功能一切正常,唯独这个上传文件会使webs崩溃。

        对于文件上传需要找到webs.c中的void websReadEvent(webs_t wp),因为我们使用的是method="post" enctype="multipart/form-data",所以处理方式在 case WEBS_POST_CLEN这里,标志为wp->flags & WEBS_MULTIPART_FORM。 这些找到后,就可以通过这条分支来处理保持上传的文件。

        在上面函数里面设置完调试语句后,将程序跑起来,然后看看问题具体产生在何处。发现,while ((rc = websGetInput(wp, &text, &nbytes)) == 0)这里在没有读取完整个文件时,竟然返回-1,返回-1表示读到EOF,或者error,导致下面执行了break,完成对文件的读取操作,接下来又会读出数据,然后整个程序挂掉。 若上传文件正常的话,会一直返回1直到读完整个文件,中途不会返回-1。 那肯定就是这里有问题了。下面就要进到websGetInput()函数里面设置调试语句,并分析。 nbytes = socketRead(wp->sid, buf, len);该处在接收文件时返回0,即没有读到数据,然后程序中对返回0的操作是return -1。ok,情况明朗了,也就是说,在上传文件过程中,有时会读取不到数据,那好,我读不到数据就继续读,怎样解决呢,  return 0;返回0表示未读完继续读,这样问题解决。

      这样解决只是治标不治本,还是有隐患的,最需要处理的就是为什么会没有读到数据。 关于文件上传这部分,只要多分析上述提到的两个函数,是最有帮助的了。

 

        在说说webs.h中定义的一些SIZE吧。WEBS_SOCKET_BUFSIZ,非常重要,此为每次从socket读取数据的长度。为了提高访问速度和上传速度,还可以增大WEBS_HEADER_BUFINC,和WEBS_BUFSIZE的大小。

        websParseRequest()函数中在提取"content-length"时,数据大小放到wp->clen里面,因此可以使用它来限制上传文件的大小。 


@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Goahead 文件上传速度过慢原因分析

 

一、Goahead WEB请求处理流程:

    开启侦听websOpenListen()-> 建立socket连接socketOpenConnection(NULL, port, websAccept, 0);并注册连接之后的响应函数websAccept;

主函数里轮训检测socket连接状态,当有连接,则相应websAccept函数;

当WEB有请求发出:

websAccept()-》创建socket处理函数socketCreateHandler(sid, SOCKET_READABLE, websSocketEvent, wp);并将socket.flags置为SOCKET_READABLE -->  进入socket事件websSocketEvent();根据socket.flags进行相应 的操作:如果为SOCKET_READABLE则为读事件--> websReadEvent(wp); 根据不同的wp.flags 和wp.states进行数据的读取,读完之后进入请求解析websParseRequest(),将wp相应标志置位,继续接受请求的数据,请求数据接收完毕,进行请求处理函数 websUrlHandlerRequest();从所有处理函数中找到请求处理函数(asp, form, cgi ...)最后关闭socket描述符,请求处理完毕。

回到主函数继续循环等待。

 

二、具体过程。

Main():

初始化

initWebs()

开启GOAHEAD服务

websOpenServer(port, retries);

                开启侦听

websOpenListen()

                    建立socket连接, 并注册连接之后的响应函数websAccept();

socketOpenConnection(NULL, port, websAccept, 0);

 

 

当侦听到有连接,运行websAccept();

websAccept();

    创建socket处理,设置socket可读标志,并注册socket事件websSocketEvent()函数。

    socketCreateHandler(sid, SOCKET_READABLE, websSocketEvent, wp);

 

socket 事件websSocketEvent()函数。

websSocketEvent();

    检测socket可读标志SOCKET_READABLE触发读wp数据事件。

    websReadEvent(wp);

        for(; ;)

            按wp.flag和wp.state轮训读取wp数据

            websGetInput();

 

            wp->state = 1或者2时,解析数据的格式.

            wp->state = 8时,接受上传文件的数据,并将其存入wp.postData;

           

            数据读完关闭socket.

            if (fd != -1) {

                gclose (fd);

                fd = -1;

            }

 

上传文件数据接收完之后,进行WEB请求处理。

            websUrlHandlerRequest(wp);

                设置环境变量。如若上二进制文件,将其进行格式处理。

                websSetEnv(wp);

                调用请求处理函数(asp或form或。。。);

                (*sp->handler)(wp, sp->urlPrefix, sp->webDir, sp->arg,

                    wp->url, wp->path, wp->query)(即:form_updateSystemFirmware);

            释放内存结束WEB读事件。

            if (text) {

                bfree(B_L, text);

            }

        结束SOCKET事件。

 

继续回到主循环等待下一个请求。

while (!finished) {

        if (socketReady(-1) || socketSelect(-1, 1000)) {

            socketProcess(-1);//处理socket事件

        }

        websCgiCleanup();

        emfSchedProcess();

}

 

 

三、 实验数据:

说明:我在websGetInput();取完数据之后在进入switch之前,添加了一打印语言,将wp->state属性打印出来。 

printf("\twp->state = %d\n",wp->state);

switch(wp->state) {

case WEBS_BEGIN:

        .

        .

        .

}

wp->state = 1 进入case WEBS_BEGIN:

wp->state = 2进入case WEBS_HEADER:

wp->state = 8进入case WEBS_POST_CLEN: (上传文件数据读取)

 

 

1.     传送较小的Makefile文件:

 

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 8

        wp->state = 8

        wp->state = 8

Get in the update form

fn (null)

bn /tmp/Makefile

begin to open file

begin to open file2222

begin to fwrite data

fwrite over

File close success

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

 

2.     传送较大的texthw

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

Get in the update form

fn (null)

bn /tmp/Makefile

begin to open file

begin to open file2222

begin to fwrite data

fwrite over

File close success

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

 

    数据分析:从两次数据中不难得出,其中数据部分是wp->state = 8的部分,开关和结尾都是一样的,所以时间的长短应该就是打印wp->state = 8的多少。因为在wp->state = 2 转wp->state = 8的时候是进行的websParesRequest();请求解析,并改变wp.state为8,所以在前面的转折点是不会出现太多的延时,在wp->state = 8 转Get in the update form时这里就是前面提到的请求处理,同样不会有太多延时。综上,上传文件的速度原因,不是因为其它延时所致的。从websReadEvent();代码中所以看出,每次读完一部分数据就要将其放进postData,还有进行一系列的处理,如果读取次数过多,这部分代码执行的频率也越高,从尔时间也越多,所以在传送同样多的数据的时候,我们要尽可能少的减少这读取次数。目前来看,貌似只有增加每次读取数据的长度才能达到这样的效果。

 

综上:文件上传速度的关键在于每次读取文件数据的buffer大小!

 

 

改变buffer之后的实验数据:( 256 –> 1024 )

1.     传送较小的文件Makefile

 

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 8

Get in the update form

fn (null)

bn /tmp/Makefile

begin to open file

begin to open file2222

begin to fwrite data

fwrite over

File close success

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

 

2.     传送较大的文件testhw

 

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

        wp->state = 8

Get in the update form

fn (null)

bn /tmp/Makefile

begin to open file

begin to open file2222

begin to fwrite data

fwrite over

File close success

        wp->state = 1

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

        wp->state = 2

 

3.     传送2M的文件系统也只用了10+秒。

 

改变这个buffer的大小,只是在传送的时候每次占用了1024的大小,而在传送完之后就释放了,所以不会有太大影响!

  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值