很多路由器都有更新固件的功能,1. 先从官网下载对应的固件保存到本机
2. 在IE上输入http://192.168.1.1,登录,转到更新固件页面
3. 选择本机的固件,点击“更新”按钮
4. 更新完毕后,按“重启路由器”,然后查看版本请问:
a). 在更新过程中,所使用的是什么协议,是TCP/UDP/HTTP吗?
b). 是如何把固件(一般都是 xxx.bin格式的文件)解析发给路由器的,需要路由器端支持吗?
c). 包括连接路由器/检查固件版本/发送新固件数据等命令,这些路由器都应该有对应的命令吗?d). 如果我用程序实现,该如何做,需要哪些资料?

解决方案 »

  1.   

    是不是可以通过
    C#的 HttpWebRequest/HttpWebResponse
    来提交数据?
      

  2.   

    是不是可以通过
    C#的 HttpWebRequest/HttpWebResponse
    来提交数据?
      

  3.   

    1.确实是通过HTTP传递数据的,先将bios流送到设备的内存中,再进行解压和写入操作。
    2.解压和写入操作不是走常规协议的。属于嵌入式范畴。
    3.路由器通过网页方式进行设置的方式全部都是通过HTTP协议走的,跟浏览器没直接关系。所以是可以通过HttpWebRequest/HttpWebResponse方式进行提交的。最好用firebug查看一下请求包的格式,再根据他的格式自己去拼包。
      

  4.   

    可以说说是如何将数据通过http传递过去的吗?
    比如说,我的这个数据在 C:\xx.bin如何通过HttpWebRequest/HttpWebResponse方式进行提交?
      

  5.   

    记得有很大部分的小路由器支持tftp更新的。
      

  6.   

    用Firebug指到更新位置时,是如下的一段代码:</form>
    <form action="/sys/update-fs/" enctype="multipart/form-data" method="post">
    <p><small>Choose file system image (filename ends with <i>.bin</i>)</small><br> <input name="fsupdate" size="40" type="file"> <br class="clear">
    <input value="Upload" type="submit">
    </p>
      

  7.   

    我要你看得是firebug中的网络那块,里面有详细的请求头信息。至于传文件。需要在请求头里面设置传输方式和编码还有长度。然后再将文件编码后发送出去。
      

  8.   

    例如请求头 ContentType要这样设置
    Content-Type: multipart/form-data;
    还要定义分块的分隔等等
    还要自己拼装Http正文
      

  9.   

    不太明白,我上面那段代码对用HttpWebRequest/HttpWebResponse方式进行提交没有帮助吗?可以详细点吗?
    非常着急啊,国庆可能都要加班,累啊 希望帮帮忙,多谢啦先
      

  10.   

    1) Update file system by POSTing the contents of the file system  (ximg.img) to /sys/update-fs 
    2) Update firmware by POSTing the contents of the firmware image (fw.bin) to /sys/update-fw
    3) Reboot the device using /sys/cmd (POST command=reboot)可以说说这是什么意思吗? 从没做过web编程,不懂啊,
    这是厂家提供的信息,
      

  11.   


    /// <summary> 
    /// 将本地文件上传到指定的服务器(HttpWebRequest方法) 
    /// </summary> 
    /// <param name="address">文件上传到的服务器</param> 
    /// <param name="fileNamePath">要上传的本地文件(全路径)</param> 
    /// <param name="saveName">文件上传后的名称</param> 
    /// <returns>成功返回1,失败返回0</returns> 
    public int Upload_Request(string address, string fileNamePath, string saveName)
    {
    int returnValue = 0;
    // 要上传的文件 
    FileStream fs = new FileStream(fileNamePath, FileMode.Open, FileAccess.Read);
    BinaryReader r = new BinaryReader(fs);

    //时间戳 
    string strBoundary = "----------" + DateTime.Now.Ticks.ToString("x");
    byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + strBoundary + "\r\n");
    //请求头部信息 

    StringBuilder sb = new StringBuilder();
    sb.Append("--");
    sb.Append(strBoundary);
    sb.Append("\r\n");
    sb.Append("Content-Disposition: form-data; name=\"");
    sb.Append("file");
    sb.Append("\"; filename=\"");
    sb.Append(saveName);
    sb.Append("\"");
    sb.Append("\r\n");
    sb.Append("Content-Type: ");
    sb.Append("application/octet-stream");
    sb.Append("\r\n");
    sb.Append("\r\n");
    string strPostHeader = sb.ToString();
    byte[] postHeaderBytes = Encoding.UTF8.GetBytes(strPostHeader);

    // 根据uri创建HttpWebRequest对象 
    HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(new Uri(address));
    httpReq.Method = "POST";
    //对发送的数据不使用缓存 
    httpReq.AllowWriteStreamBuffering = false;
    //设置获得响应的超时时间(300秒) 
    httpReq.Timeout = 300000;
    httpReq.ContentType = "multipart/form-data; boundary=" + strBoundary;
    long length = fs.Length + postHeaderBytes.Length + boundaryBytes.Length;
    long fileLength = fs.Length;
    httpReq.ContentLength = length;

    try
    {
    //每次上传4k 
    int bufferLength = 4096;
    byte[] buffer = new byte[bufferLength];
    //已上传的字节数 
    long offset = 0;
    //开始上传时间 
    DateTime startTime = DateTime.Now;
    int size = r.Read(buffer, 0, bufferLength);
    Stream postStream = httpReq.GetRequestStream();
    //发送请求头部消息 
    postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
    while (size > 0)
    {
    postStream.Write(buffer, 0, size);
    size = r.Read(buffer, 0, bufferLength);
    }
    //添加尾部的时间戳 
    postStream.Write(boundaryBytes, 0, boundaryBytes.Length);
    postStream.Close();
    //获取服务器端的响应 
    WebResponse webRespon = httpReq.GetResponse();
    Stream s = webRespon.GetResponseStream();
    StreamReader sr = new StreamReader(s);
    //读取服务器端返回的消息 
    String sReturnString = sr.ReadLine();
    s.Close();
    sr.Close();

    if (sReturnString == "Success")
    {
    returnValue = 1;
    }
    else if (sReturnString == "Error")
    {
    returnValue = 0;
    }
    }
    catch
    {
    returnValue = 0;
    }
    finally
    {
    fs.Close();
    r.Close();
    }
    return returnValue;
    }
    用这段代码将文件上传到指定位置
      

  12.   

    1) Update file system by POSTing the contents of the file system (ximg.img) to /sys/update-fs 
    上传镜像文件到  "192.168.0.1(路由器的IP)/sys/update-fs" 保存时文件名为 ximg.img
    调用上面的方法
    string url = "192.168.0.1(路由器的IP)/sys/update-fs" ;
    Upload_Request(url,"硬盘上的镜像文件路径","ximg.img");2) Update firmware by POSTing the contents of the firmware image (fw.bin) to /sys/update-fw
    上传更新包文件到  "192.168.0.1(路由器的IP)/sys/update-fw" 保存时文件名为 fw.bin
    调用上面的方法
    string url = "192.168.0.1(路由器的IP)/sys/update-fw" ;
    Upload_Request(url,"硬盘上的更新包文件路径","fw.bin");3) Reboot the device using /sys/cmd (POST command=reboot)
    重启路由器即可
    也可以Post command=reboot 到 "192.168.0.1(路由器的IP)/sys/cmd"
      

  13.   

    1) Update file system by POSTing the contents of the file system (ximg.img) to /sys/update-fs 
    上传镜像文件到 "192.168.0.1(路由器的IP)/sys/update-fs" 保存时文件名为 ximg.img
    调用上面的方法
    string url = "192.168.0.1(路由器的IP)/sys/update-fs" ;
    Upload_Request(url,"硬盘上的镜像文件路径","ximg.img");2) Update firmware by POSTing the contents of the firmware image (fw.bin) to /sys/update-fw
    上传更新包文件到 "192.168.0.1(路由器的IP)/sys/update-fw" 保存时文件名为 fw.bin
    调用上面的方法
    string url = "192.168.0.1(路由器的IP)/sys/update-fw" ;
    Upload_Request(url,"硬盘上的更新包文件路径","fw.bin");3) Reboot the device using /sys/cmd (POST command=reboot)
    重启路由器即可
    也可以Post command=reboot 到 "192.168.0.1(路由器的IP)/sys/cmd"调用下面的方法
    PostData("192.168.0.1(路由器的IP)/sys/cmd", "command=reboot");
    /// <summary>
    /// 向指定网址发送请求
    /// </summary>
    /// <param name="_url">地址</param>
    /// <param name="content">post的正文(为null则使用Get方式请求网址)</param>
    /// <returns>是否成功</returns>
    public static bool PostData(string _url, string content)
    {
    bool reutrnValue = false;
    try
    {
    HttpWebResponse response = null;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url); if ((content ?? string.Empty).Length > 0)
    {
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    byte[] bytes = Encoding.UTF8.GetBytes(content);
    request.ContentLength = bytes.Length; Stream stream = request.GetRequestStream();
    stream.Write(bytes, 0, bytes.Length);
    stream.Close();
    } response = request.GetResponse() as HttpWebResponse;

    reutrnValue = response.StatusCode == HttpStatusCode.OK;
    response.Close();
    }
    catch (Exception ex)
    {
    reutrnValue = false;
    }
    finally
    {
    } return reutrnValue;
    }
      

  14.   

    1:先将bin文件上传至路由器。
    2:路由器系统程序检测到新的Bin文件,将其写入Rom。
    3:写入完毕后重启路由器系统完成系统更新。
      

  15.   

    有问题的地方多了,有可能上面需要登录
    需要提供cookie你可能还得完成登录的动作才能正确上传
      

  16.   

    想请教一下:这段代码是做什么的?            StringBuilder sb = new StringBuilder();
                sb.Append("--");
                sb.Append(strBoundary);
                sb.Append("\r\n");
                sb.Append("Content-Disposition: form-data; name=\"");
                sb.Append("file");
                sb.Append("\"; filename=\"");
                sb.Append(saveName);
                sb.Append("\"");
                sb.Append("\r\n");
                sb.Append("Content-Type: ");
                sb.Append("application/octet-stream");
                sb.Append("\r\n");
                sb.Append("\r\n");
                string strPostHeader = sb.ToString();
                byte[] postHeaderBytes = Encoding.UTF8.GetBytes(strPostHeader);
    ................
                httpReq.ContentType = "multipart/form-data; boundary=" + strBoundary;
                long length = fs.Length + postHeaderBytes.Length + boundaryBytes.Length;
                long fileLength = fs.Length;
                httpReq.ContentLength = length;//这段httpReq.ContentType = "multipart/form-data; boundary=" + strBoundary;
    // 可以改为这段吗?
    httpReq.ContentType = "multipart/form-data;";
      

  17.   

    说实在我还真没见过哪个路由器无需验证用户身份就可以更新固件的。给你一个我的请求。 /// <summary>
    /// 请求指定网址
    /// </summary>
    /// <param name="_url">网址</param>
    /// <param name="content">post的数据 null的话则使用get方式请求</param>
    /// <param name="cookie">set-cookie的数据</param>
    /// <param name="referer">来源网址</param>
    /// <param name="username">http用户名</param>
    /// <param name="password">http密码</param>
    /// <returns>web返回对象</returns>
        public static HttpWebResponse HttpWebRequest(string _url, string content, string cookie, string referer, string username, string password)
        {
            HttpWebResponse response = null;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);            if ((cookie ?? string.Empty).Length > 0)
                {
                    request.CookieContainer = new CookieContainer();
                    request.CookieContainer.SetCookies(new Uri(_url), cookie);
                }
                
                if((username ?? string.Empty).Length > 0)
                {
                    request.Credentials = new System.Net.NetworkCredential(username, password ?? string.Empty);
                }            if((referer ?? string.Empty).Length > 0)
                {
                    request.Referer = referer;
                }
                
                if((content ?? string.Empty).Length > 0)
                {
                    request.Method = "POST";
                    request.ContentType = "application/x-www-form-urlencoded";
                    byte[] bytes = Encoding.UTF8.GetBytes(content);
                    request.ContentLength = bytes.Length;
                    
                    Stream stream = request.GetRequestStream();
                    stream.Write(bytes, 0, bytes.Length);
                    stream.Close();
                }
                            response = request.GetResponse() as HttpWebResponse;
                
            }
            catch(Exception ex)
            {
            }
            finally
            {
            }
            
            return response;
        } /// <summary> 
    /// 将本地文件上传到指定的服务器(HttpWebRequest方法) 
    /// </summary> 
    /// <param name="address">文件上传到的服务器</param> 
    /// <param name="fileNamePath">要上传的本地文件(全路径)</param> 
    /// <param name="saveName">文件上传后的名称</param> 
    /// <param name="cookie">set-cookie的数据</param>
    /// <returns>成功返回1,失败返回0</returns> 
    public int Upload_Request(string address, string fileNamePath, string saveName, string cookie)
    {
    int returnValue = 0;
    // 要上传的文件 
    FileStream fs = new FileStream(fileNamePath, FileMode.Open, FileAccess.Read);
    BinaryReader r = new BinaryReader(fs); //时间戳 
    string strBoundary = "----------" + DateTime.Now.Ticks.ToString("x");
    byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + strBoundary + "\r\n");
    //请求头部信息  StringBuilder sb = new StringBuilder();
    sb.Append("--");
    sb.Append(strBoundary);
    sb.Append("\r\n");
    sb.Append("Content-Disposition: form-data; name=\"");
    sb.Append("file");
    sb.Append("\"; filename=\"");
    sb.Append(saveName);
    sb.Append("\"");
    sb.Append("\r\n");
    sb.Append("Content-Type: ");
    sb.Append("application/octet-stream");
    sb.Append("\r\n");
    sb.Append("\r\n");
    string strPostHeader = sb.ToString();
    byte[] postHeaderBytes = Encoding.UTF8.GetBytes(strPostHeader); // 根据uri创建HttpWebRequest对象 
    HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(new Uri(address));

    if ((cookie ?? string.Empty).Length > 0)
    {
    httpReq.CookieContainer = new CookieContainer();
    httpReq.CookieContainer.SetCookies(new Uri(address), cookie);
    }

    httpReq.Method = "POST";
    //对发送的数据不使用缓存 
    httpReq.AllowWriteStreamBuffering = false;
    //设置获得响应的超时时间(300秒) 
    httpReq.Timeout = 300000;
    httpReq.ContentType = "multipart/form-data; boundary=" + strBoundary;
    long length = fs.Length + postHeaderBytes.Length + boundaryBytes.Length;
    long fileLength = fs.Length;
    httpReq.ContentLength = length;


    try
    {
    //每次上传4k 
    int bufferLength = 4096;
    byte[] buffer = new byte[bufferLength];
    //已上传的字节数 
    long offset = 0;
    //开始上传时间 
    DateTime startTime = DateTime.Now;
    int size = r.Read(buffer, 0, bufferLength);
    Stream postStream = httpReq.GetRequestStream();
    //发送请求头部消息 
    postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
    while (size > 0)
    {
    postStream.Write(buffer, 0, size);
    size = r.Read(buffer, 0, bufferLength);
    }
    //添加尾部的时间戳 
    postStream.Write(boundaryBytes, 0, boundaryBytes.Length);
    postStream.Close();
    //获取服务器端的响应 
    WebResponse webRespon = httpReq.GetResponse();
    Stream s = webRespon.GetResponseStream();
    StreamReader sr = new StreamReader(s);
    //读取服务器端返回的消息 
    String sReturnString = sr.ReadLine();
    s.Close();
    sr.Close(); if (sReturnString == "Success")
    {
    returnValue = 1;
    }
    else if (sReturnString == "Error")
    {
    returnValue = 0;
    }
    }
    catch
    {
    returnValue = 0;
    }
    finally
    {
    fs.Close();
    r.Close();
    }
    return returnValue;
    } /// <summary>
    /// 向指定网址发送请求
    /// </summary>
    /// <param name="_url">地址</param>
    /// <param name="content">post的正文(为null则使用Get方式请求网址)</param>
    /// <param name="cookie">set-cookie的数据</param>
    /// <returns>是否成功</returns>
    public static bool HttpWebRequest(string _url, string content, string cookie)
    {
    bool reutrnValue = false;
    try
    {
    HttpWebResponse response = null;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url); if ((cookie ?? string.Empty).Length > 0)
    {
    request.CookieContainer = new CookieContainer();
    request.CookieContainer.SetCookies(new Uri(_url), cookie);
    }

    if ((content ?? string.Empty).Length > 0)
    {
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    byte[] bytes = Encoding.UTF8.GetBytes(content);
    request.ContentLength = bytes.Length; Stream stream = request.GetRequestStream();
    stream.Write(bytes, 0, bytes.Length);
    stream.Close();
    }
    response = request.GetResponse() as HttpWebResponse;

    reutrnValue = response.StatusCode == HttpStatusCode.OK;
    response.Close();
    }
    catch (Exception ex)
    {
    reutrnValue = false;
    }
    finally
    {
    } return reutrnValue;
    }
    HttpWebResponse response = HttpWebRequest("路由器地址", null, null, null, 用户名, 密码);
    //获取cookie用于参数 <param name="cookie">set-cookie的数据</param>
    string cookie = response.Headers["set-cookie"];
    response.Close();
    //再用带cookie的Upload_Request上传文件
    Upload_Request("192.168.0.1(路由器的IP)/sys/update-fw","硬盘路径","保存文件名",cookie);
    //传另外一个文件
    (省略)
    //调用页面重启路由器
    PostData("192.168.0.1(路由器的IP)/sys/cmd", "command=reboot",cookie);
      

  18.   

    这个是多片段表单提交的格式,你看看http协议吧。会了就知道什么意思了
      

  19.   

    Upload_Request("192.168.0.1(路由器的IP)/sys/update-fw","硬盘路径","保存文件名",cookie);
    这里的地址要不要带“http://”???
    即:Upload_Request("http://192.168.0.1(路由器的IP)/sys/update-fw","硬盘路径","保存文件名",cookie);
      

  20.   

    可能是我理解错了,我想这样,
    首先,实现选择目标文件的全路径,
    然后,实现犹如点击IE里的“Upload“按钮一样的功能,如果这样做,就好象是使用IE一样了,是这样吗?
      

  21.   


    gzdiablo,由此可以断定是用http协议来更新固件的吗?
      

  22.   

    写数据时,弹出这么一个错误:Unable to write data to the transport connection: 远程主机强迫关闭了一个现有的连接。
      

  23.   

    厂家说明信息里还说“确保发送数据时不要以chunked encoding格式”
      

  24.   

    To gzdiablo:在你给的函数
    int Upload_Request(string address, string fileNamePath, string saveName)
    中加入下面两句后,就可以更新其中的一个固件,但是另外一个却不可以,是怎么回事呢?
    httpReq.ProtocolVersion = HttpVersion.Version11;
    httpReq.SendChunked = false;麻烦大家要回复的先看完别人的回复,以免重复,谢谢撒
      

  25.   

    这个,,直接一个webbrowser控件后台模拟操作多简单。
    另外,不少路由器之类的东东都支持telnet操作的。
      

  26.   

    搞定了,顺便帮看看这个:
    http://topic.csdn.net/u/20101008/13/99880819-a1b4-4181-a022-188c6efec0e9.html