C get_arg()无法与wake_up()一起使用
我在stream3.c中的xbuf_xcat下添加了printf语句,如下所示:C get_arg()无法与wake_up()一起使用,c,g-wan,C,G Wan,我在stream3.c中的xbuf_xcat下添加了printf语句,如下所示: xbuf_xcat(reply, "%x\r\n%s\r\n", len, readbuf); char *client_arg_time=0; get_arg("time=", & client_arg_time, argc, argv); printf("%s\n", client_arg_time); 它应该从http参数打印时间。 但是它打印空值,除了第一个 我的代码怎么了? 我使用的是ubunt
xbuf_xcat(reply, "%x\r\n%s\r\n", len, readbuf);
char *client_arg_time=0;
get_arg("time=", & client_arg_time, argc, argv);
printf("%s\n", client_arg_time);
它应该从http参数打印时间。
但是它打印空值,除了第一个
我的代码怎么了?
我使用的是ubuntu 12.04,G-WAN 4.3.14。
编辑=======================
http的uri?time=1223456,因此get_argtime=,…函数获取1223456并打印到屏幕。可以,但只打印一次。当wake_up唤醒脚本时,它应该打印另一个1223456,但它打印空值。如果检查gwan中的示例stream3.c,您可以找到xbuf\u xcatreply的行,%x\r\n%s\r\n,len,readbuf;如下图所示,靠近底部。引用gwan示例stream3.c:
#include "gwan.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define NBR_CHUNKS "10"
// ----------------------------------------------------------------------------
// popen replacement (GLIBC's popen() does not want to work without buffers)
// ----------------------------------------------------------------------------
int run_cmd(char *cmd_to_run)
{
const u32 cmd_len = strlen(cmd_to_run) + 1;
char cmd[cmd_len + 8];
snprintf(cmd, sizeof(cmd), "%s 2>&1", cmd_to_run);
// create a one-way communication channel (a pipe)
// (bytes written on fd[1] can be read from fd[0])
int fd[2]; if(pipe(fd)) return 0;
const int f = fd[0];
const pid_t pid = fork(); // fork is needed to hook the process stdout I/O
switch(pid)
{
case -1: // error
close(fd[0]);
close(fd[1]);
return 0;
case 0: // new child process, make child's stdout use our fd
dup2(fd[1], 1); // close(fd2) && fd2 = fd
close(fd[0]);
close(fd[1]);
// replace the current process image with a new process image
char c1[] = "/bin/sh", c2[] = "sh", c3[] = "-c";
char *args[] = { c2, c3, cmd, 0 };
execvp(c1, args);
exit(127);
}
// this is the parent process
close(fd[1]);
return f;
}
// ----------------------------------------------------------------------------
// our (minimalist) per-request context
// ----------------------------------------------------------------------------
typedef struct { int f; } data_t;
int main(int argc, char *argv[])
{
char readbuf[1024] = {0};
// get the server 'reply' buffer where to write our answer to the client
xbuf_t *reply = get_reply(argv);
// -------------------------------------------------------------------------
// step 1: setup a per-request context
// -------------------------------------------------------------------------
data_t **data = (void*)get_env(argv, US_REQUEST_DATA);
if(!*data) // we did not setup our per-request structure yet
{
// create a per-request memory pool
if(!gc_init(argv, 4070)) // we can call gc_alloc() to consume 4070 bytes
return 503; // could not allocate memory!
*data = gc_malloc(argv, sizeof(data_t)); // allocate our context
if(!*data) return 503; // not possible here, but better safe than sorry
// ----------------------------------------------------------------------
// step 2: run an asynchrone (or incremental) job
// ----------------------------------------------------------------------
// run the "ping -c 10 127.0.0.1" command
(*data)->f = run_cmd("ping -c " NBR_CHUNKS " 127.0.0.1");
if((*data)->f == 0) // error
{
int ret = strerror_r(errno, readbuf, sizeof(readbuf));
xbuf_cat(reply, ret ? "unknown error" : readbuf);
return 200;
}
// ----------------------------------------------------------------------
// tell G-WAN when to run this script again (for the same request)
// ----------------------------------------------------------------------
wake_up(argv, (*data)->f, WK_FD); // when fd buffer has data
// ----------------------------------------------------------------------
// send chunked encoding HTTP header and HTTP status code
// ----------------------------------------------------------------------
char head[] = "HTTP/1.1 200 OK\r\n"
"Connection: close\r\n"
"Content-type: text/html; charset=utf-8\r\n"
"Transfer-Encoding: chunked\r\n\r\n"
"5\r\n<pre>\r\n";
xbuf_ncat(reply, head, sizeof(head) - 1);
}
// -------------------------------------------------------------------------
// step 3: repeatedly read (and send to client) ping's incremental reply
// -------------------------------------------------------------------------
// fetch the command output and store it in the 'reply' buffer
const int len = read((*data)->f, readbuf, sizeof(readbuf));
if(len <= 0) // done
{
close((*data)->f);
// note that malloc() would have to free the 'data' context here
// (gc_malloc() is automatically freed, along with its memory pool
// so there's no need for an explicit free)
// end the on-going chunked encoding
char end[] = "6\r\n</pre>\r\n0\r\n\r\n";
xbuf_ncat(reply, end, sizeof(end) - 1);
wake_up(argv, 0, WK_FD); // 0:no more wake-up please
return RC_NOHEADERS; // RC_NOHEADERS: do not generate HTTP headers
}
// -------------------------------------------------------------------------
// format reply to use chunked encoding
// -------------------------------------------------------------------------
// anatomy of a chunked response:
//
// HTTP/1.1 200 OK [CRLF] <-+
// Content-Type: text/html [CRLF] | HTTP headers
// Transfer-Encoding: chunked [CRLF] <-+
// [CRLF]
// 1a; optional-stuff-here [CRLF] // hexadecimal length
// abcdefghijklmnopqrstuvwxyz [CRLF] // data (ASCII/binary)
// 10 [CRLF] // hexadecimal length
// 1234567890abcdef [CRLF] // data (ASCII/binary)
// 0 [CRLF] // 0: end of chunks
// optional-footer: some-value [CRLF] // can be HTTP headers
// optional-another-footer: another-value [CRLF] // can be HTTP headers
// [CRLF]
xbuf_xcat(reply, "%x\r\n%s\r\n", len, readbuf);
// HERE! added code.
char *client_arg_time=0;
get_arg("time=", & client_arg_time, argc, argv);
printf("%s\n", client_arg_time);
// End of my added code.
// -------------------------------------------------------------------------
// return code
// -------------------------------------------------------------------------
// RC_NOHEADERS: do not generate HTTP headers
// RC_STREAMING: call me again after send() is done
return RC_NOHEADERS + RC_STREAMING;
}
// ============================================================================
// End of Source Code
// ============================================================================
如果wake_up以相同的配置运行请求,我不是舒尔 我会在数据结构上保存所有需要的东西,它是gc\u alloc,因为我们知道它是一个存储区域,由唤醒调用保存和使用。 因此,首先扩展数据结构以适应您的信息。在第2步之前设置它,并在当前使用它的地方阅读它
这缺少一些上下文。这是G-WAN的源代码吗?你的修改应该做什么?为什么您认为客户机参数时间此时不应为空?“第一个”指的是什么?uri是?time=1223456,因此get_argtime=,。。。获取1223456并打印到屏幕。可以,但只限于第一轮。稍后,当wake_up调用脚本时,它将打印null而不是1223456。如果检查gwan中的示例stream3.c,您可以找到xbuf\u xcatreply的行,%x\r\n%s\r\n,len,readbuf;我知道如何使用持久指针将数据存储在kv store中。但它不符合我的需要。我需要同一个servlet每次执行的uniqe信息。所以,*data->time不适合我的需要,因为它不是uniqe信息。servlet的每次执行都指向指向相同数据的指针。例如,每次调用servlet时,都会为wake_up函数创建一个fd,并在servlet被唤醒时从该fd获取数据。每个执行都应该有自己的uniqe fd。我试着从get_agrv或get_env获得这所大学的信息。到目前为止,只要通过wake_唤醒servlet,我就可以获取文件和服务时间。但这两个信息仍然不能是每次执行的唯一信息。因此,我尝试get_arg从客户端获取uniqr信息,但面临上述问题,即get_agr返回空值。uniqe信息用于创建uniqe密钥,用于将fd存储在kv存储中。然后,每当servlet被唤醒时,我就可以返回store fd指针。我发现了另一个信息,即get_envargv,SESSION_ID。在kv store中创建uniqe密钥有用吗?是的,每当创建http连接时,您将获得一个在http握手期间唯一的SESSION_ID。但它不会保持其他连接。。。为此,您需要将其作为cookie发送回。
typedef struct {int f;u32 time;} data_t;
...
char *client_arg_time=0;
get_arg("time=", &client_arg_time, argc, argv);
(*data)->time = atol(client_arg_time);
...
// HERE! added code.
printf("%u\n", (*data)->time);
// End of my added code.