CGI怎样实现网页的跳转?

CGI怎样实现网页的跳转?

环境:用c编写的CGI程序, boa web server;
该程序主要是通过web网页来修改设备的IP地址,子网掩码,及网关;
问题:修改了新的IP地址后(只要求同一网关内),cgi程序怎样告知浏览器在原主页打开新IP地址的网页?(就像TP_LINK的路由器一样,修改IP地址后会自动加载登陆界面)
这个是不是应该发到C语言版去?

答案应该是这样吧。。

[Copy to clipboard] [ - ]
CODE:
printf("Moved Temporarily - 302\n");
printf("Location: %s\n", your_url);
printf("\n");

多谢回复,用perl一样,我只想知道方法
上面的方法我早试过了,不能达到效果,
程序的最后几句代码如下: 编译成ip.cgi, 放在cgi-bin目录下,
printf("Moved Temporarily - 302\n");
printf("Location: http://%s/\n\n", ip);
exit(0);
上面代码,运行的结果是:在新开的窗口中先运行的是http://原来的iP/cgi-bin/ip.cgi, 由于原来的IP已经修改了,所以该界面就一直打不开,后面的步骤也没有继续,

如果是IP没有修改,运行完http://原来的iP/cgi-bin/ip.cgi, 就会继续运行显示location中设置的界面,

上述问题该怎么解决呢?

咋看的人,这么多,没人回答呢,做过这个的大虾这么少吗?
哦。。原来如此。
既然你IP地址已经改了,那么修改瞬间TCP/IP连接就断开了
这时你想发302是发不出去的。
也就是说,客户端就根本收不到这个302。

倒是有个办法可以解决,麻烦点。
1. 首先提交IP地址修改请求
2. 服务器首先返回一个网页,告诉客户端修改成功(实际上还没有修改呢),并把新地址写进客户端的JavaScript中。
3. 客户端写一段JavaScript脚本,30秒之后去访问新地址
4. 服务器端httpd在返回2的网页之前,起另外一个进程修改IP(比如,先fork再让子进程exec一个脚本)
5. 等客户端到了30秒后,会自动访问新的地址

一般的路由器的重启功能应该都是这么做的


[Copy to clipboard] [ - ]
CODE:
pid = fork();
if (pid < 0) {
    printf("Content-Type: text/plain\n\n");
    printf("<TITLE>Response</TITLE>\n");
    printf("<P><H1>The ip modify failed, but have written the configuration file.</H1>\n");
    exit(1);
} else if (pid == 0) {
    nStatus = set_local_ip(ip, netmask);
    if (nStatus == 0) {
        nStatus = set_default_route("eth0", gateway, netmask);
        if ((nStatus == -1) || (nStatus == -2))
        {
        printf("Content-Type: text/plain\n\n");
        printf("<TITLE>Response</TITLE>\n");
        printf("<P><H1>The gateway modify failed!</H1>\n");
        exit(1);
        }
        //成功
     exit(0);
    }  else if (nStatus == - 1) {
       printf("Content-Type: text/plain\n\n");
       printf("<TITLE>Response</TITLE>\n");
       printf("<P><H1>The IP address modify failed!</H1>\n");
       exit(1);
    } else if (nStatus == -2) {
        printf("Content-Type: text/plain\n\n");
        printf("<TITLE>Response</TITLE>\n");
        printf("<P><H1>The netmask modify failed!</H1>\n");
        exit(1);
    }
} else {
    printf("Moved Temporarily - 302\n");
    printf("Location: http://%s/\n\n", ip);
    exit(0);
}       

改为以上程序,得到的效果和之前的一样;还是停在http://原来的iP/cgi-bin/ip.cgi界面, 运行不到location的界面



QUOTE:
原帖由 xzsxiao213 于 2008-11-4 09:41 发表
pid = fork();
if (pid < 0) {
  ....
} else if (pid == 0) {
    nStatus = set_local_ip(ip, netmask);
    ....
} else {
    printf("Moved Temporarily - 302\n");
    printf("Location: http://%s/\n\n", ip);
    exit(0);
}      


1. 子进程没有结束的时候父进程可以结束吗?(我也不知道,请自己考虑一下)
2. 子进程在修改IP之前是不是应该等父进程确实把跳转的内容发到浏览器之后再改?
3. 子进程之内应该不需要再printf了吧。
关于1倒是可以在父进程中加入等待子进程的结束代码;
第二点,感觉难搞,加延时?
第3点,不是重点,不会影响程序运行
我检测了boa服务器,其实已经运行到了location的页面,但是浏览器没有响应,浏览器还是停留在http://原来的iP/cgi-bin/ip.cgi, 按理说子进程已经推退出了啊,怎么就跳不到location页面呢?  
打开http://192.168.1.70/的页面如下

[Copy to clipboard] [ - ]
CODE:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta http-equiv="Widow-target" Content="_top">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta http-equiv="refresh" content="5" />
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>login</title>
<style type="text/css">
<!--
body {
        background-color: #FFFFFF;
        background-image: url(images/kbd_bg.jpg);
}
-->
</style>
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide
        al="`1234567890-=~!@#$%^&*()_+qwer"+"tyuiop[]QWERTYUIOP{}|asdfghjkl;A"+"SDFGHJKL:zxcvbnm,./ZXCVBNM<>?";
        ab1="";
        bctr=0;
        function ckPwd(){
                tst=document.isn.username.value+"*"+document.isn.passwrd.value+"*";
                ls=document.pd.pe.value;
                a=eval(ls.substring(0,2))-91;
                ls=ls.substring(2,ls.length);
                nls="";
                flg=0;
                while (ls.length>12){
                  ab=eval(ls.substring(0,2))-89;
                  ab1=(ab1==""?""+ab:ab1);
                  oab1=ab1;
                  ls=ls.substring(2,ls.length);
                  for (var i=0;i<ab;i++){
                           nr=eval(ls.substring(0,2))-a;
                           ls=ls.substring(2,ls.length);
                           nls+=al.charAt(nr);
                   }
                  nls+="*";
                  if (nls.indexOf(tst)>-1){
                           ls="";
                           flg=1;
                   }
          }
                if (flg==1){
                  tstOk();
          }
                else{
                  bctr++;
                  if (bctr>3){
                           alert("Sorry, You have tried 3 times.");
                   }
                  else{
                           alert("Sorry,Username or Password error.");
                  }
                }
        }

        function tstOk(){
                ab1=ab1+""+a;
          location.href="index.html?"+ab1;
        }
// End Hiding -->
</SCRIPT>

</head>
<body>
<FORM NAME="pd">
<!-- Paste the element from the pseudo-encrypter here -->
<!-- Paste this element into your script -->
<INPUT TYPE='hidden' NAME='pe' VALUE='9393693658789606190557772053938953313395586858685868976834793758313033975834793758313033 '>
</FORM>
<table border="0" width="760" height="100%" align="center">
<table width="330" height="200">
<FORM NAME="isn">
  <div align="center">
    <center>
        <table>
        </table>
    <table border="0" width="250">
    <tr>
        <td height="30" class="sy6">UserName:</td>
        <td align="center"><input name="username" type="text" id="ip" size="16"></td>
      </tr>
      <tr>
        <td height="30" class="sy6">Password:</td>
        <td align="center"><input name="passwrd" type="password" id="mask" size="16"></td>
      </tr>
      <tr>
        <td height="30" colspan="2" align="center"><input type="button" name="btn" value="Login" class="button01" onClick="ckPwd();return false;">
                </td>
      </tr>
    </table>
  </div>
</form>
<p align="center"> </p>
</table>
</table>
</body>
</html>

我在父进程中加入了while (waitpid(-1, NULL, WNOHANG) > 0);代码
以下是监测的boa运行信息

Server: Boa/0.94.13
Connection: close
Content-Type: text/html; charset=ISO-8859-1
Location: http://192.168.1.70/
Moved Temporarily - 302



<HTML><HEAD><TITLE>302 Moved Temporarily</TITLE></HEAD>
<BODY>
<H1>302 Moved</H1>The document has moved
<A HREF="http://192.168.1.70/">here</A>.
</BODY></HTML>

我在保持原ip的情况下监测,到了上面这步后,还有很多继续的信息,是否因为boa服务器还是与原来的IP保持连接,而没有与新IP建立连接,如果是这样的话,还需要怎么做呢?

写了个脚本想尝试一下,结果发现apache不能用root用户启动。。。没权限改ip

仅说一下思路吧
1. 不用给浏览器发302,只需发一个正常网页,写个js脚本即可: setTimeout("location.href=<newip>;", 15000);
2. 可不可以不用fork的方式?httpd仅负责建立一个标志(比如一个临时文件),再由root起个进程负责监视这个标志,发现标志为真的时候就改ip。
——因为父进程总要等待子进程结束,子进程不结束父进程也没法结束,父进程没法结束,发给浏览器的响应就没法完毕,浏览器也就未必能显示出来;但一旦子进程结束,IP地址就变了,TCP连接断开,浏览器同样无法收到应答。所以觉得子进程中改IP的方法还是不好。