搜索
bottom↓
回复: 11

C#中的HttpWebRequest底层是如何实现的? yeelink上传图片

[复制链接]

出0入4汤圆

发表于 2015-3-24 20:11:24 | 显示全部楼层 |阅读模式
用C#写了个小工具软件上传图片到,yeelink.net功能正常,现在需要把这个功能移植到芯片上实现,需要知道SOCKET层的实现细节,了解的朋友指点下,谢谢!
上传代码如下
                HttpWebRequest http = (HttpWebRequest)WebRequest.Create("http://api.yeelink.net/v1.1/device/" + DeviceID.Text + "/sensor/" + SensorID.Text + "/datapoints");

                http.Accept = "application/json";
                http.ContentType = "application/json";
                http.Headers.Add("U-ApiKey", APIKey.Text);
                http.Method = "POST";

                FileStream fs = File.OpenRead(imagefile);
                byte[] image_bytes = ConvertFileToByteBuffer(fs);
                Stream newStream = http.GetRequestStream();
                newStream.Write(image_bytes, 0, image_bytes.Length);
                newStream.Close();
                fs.Close();

                response = http.GetResponse();

                Stream stream = response.GetResponseStream();
                StreamReader sr = new StreamReader(stream);
                String content = sr.ReadToEnd();
                responsetext.Text = content;

                stream.Close();
上传了一幅5346字节大小的图片,抓包工具显示如下

HTTP之前的几个TCP包感觉是在上传图片数据,但是如何拆分的不清楚,1514*3+1020 不等于 5346字节

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入70汤圆

发表于 2015-3-24 20:25:26 | 显示全部楼层
本帖最后由 SkyGz 于 2015-3-24 20:35 编辑

就是TCP协议 连接 主域名,  连上后, 发送 HTTP头信息(包含防问的网址URL, 以及COOKIE, 提交的表单参数后),  发送完头信息后, 接着提交 文件数据即可

抓包工具,  看 ID为 15229,  15299 这两个 包 就知道了.

贴上一段 以前 DELPHI写的函数,  用于 下载的,  其实 你要上传的, 实现方法类似,  了解一个方向就知道了


Function TFrmMain.Download(ServerFileName, LocalFileName, ProxyHost, ProxyPort, ProxyUser, ProxyPass: String; IsProxy: Boolean): Boolean;
Var
  Header: String;
  Buf: Array[0..4095] Of byte;
  Rec: Longint;
  FF: File;
  Cmd: String; //这一行的内容
  Reclen, Real_Reclen: Longint; //服务器返回的长度;实际已经收到的长度
  Total: Longint; //数据总长
  SerAddr: String; //服务器地址
  ServerFile: String; //服务器端文件
  DownPos: Longint; //上次下载的位置
  IsRec: Boolean; //是否可以接收
  ServerPort: Integer;
Begin
  Try
    result := false;
    IsRec := false;
    IsStop := false;
    //创建保存到本地下载的文件,
    AssignFile(FF, LocalFileName);
    If FileExists(LocalFileName) = true Then
    Begin
      Reset(FF, 1);
      DownPos := FileSize(FF);
    End
    Else
    Begin
      Rewrite(FF, 1);
      DownPos := 0;
    End;
    Seek(FF, DownPos);
    //连接网站服务器
    CS.Active := false;
    If IsProxy Then
    Begin
      CS.Host := GetHost(ProxyHost, ServerPort);
      CS.Port := StrToInt(ProxyPort);
    End
    Else
    Begin
      CS.Host := GetHost(ServerFileName, ServerPort);
      CS.Port := ServerPort;
    End;
    CS.ClientType := ctBlocking;

   //获取访问的 网址, 即下载文件的URL
    SerAddr := GetHost(ServerFileName, ServerPort);
    ServerFile := GetFile(ServerFileName);

    //发送HTTP头信息给服务器,  查询待下载文件大文件大小
    CS.Active := true;
    Header := '';
    If IsProxy Then
    Begin
      Header := Header + 'HEAD Http://' + SerAddr + ':' + IntToStr(ServerPort) + '/' + ServerFile + ' HTTP/1.0' + #13#10;
      If ProxyUser <> '' Then Header := Header + 'Proxy-Authorization: Basic ' + Base64EnCodeStr(ProxyUser + ':' + ProxyPass) + #13#10;
    End
    Else Header := Header + 'HEAD /' + ServerFile + ' HTTP/1.1' + #13#10;
    Header := Header + 'Pragma: no-cache' + #13#10;
    Header := Header + 'Cache-Control: no-cache' + #13#10;
    Header := Header + 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)' + #13#10;
    Header := Header + 'Host: ' + SerAddr + ':' + IntToStr(ServerPort) + #13#10;
    If IsProxy Then Header := Header + 'Proxy-Connection: Keep-Alive' + #13#10 Else Header := Header + 'Connection: Keep-Alive' + #13#10;
    Header := Header + #13#10;
    CS.Socket.SendText(Header);

    //服务器返回 待下载文件的文件大小.
    Total := 0;
    While CS.Active = true Do
    Begin
      If IsStop = true Then Break;
      Cmd := SocketRec(CS.Socket, 60 * 1000);
      If Pos(LowerCase('Content-Length: '), LowerCase(Cmd)) = 1 Then Total := StrToInt(Trim(Copy(Cmd, Length('Content-Length: ') + 1, Length(Cmd))));
      If Cmd = #13#10 Then Break;
      application.ProcessMessages;
    End;
    //获取下载文件数据
    CS.Active := false;
    CS.Active := true;
    Header := '';
    If IsProxy Then
    Begin
      Header := Header + 'GET Http://' + SerAddr + ':' + IntToStr(ServerPort) + '/' + ServerFile + ' HTTP/1.0' + #13#10;
      If ProxyUser <> '' Then Header := Header + 'Proxy-Authorization: Basic ' + Base64EnCodeStr(ProxyUser + ':' + ProxyPass) + #13#10;
    End
    Else Header := Header + 'GET /' + ServerFile + ' HTTP/1.1' + #13#10;
    Header := Header + 'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*' + #13#10;
    Header := Header + 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)' + #13#10;
    Header := Header + 'RANGE: bytes=' + IntToStr(DownPos) + '-' + #13#10;
    Header := Header + 'Host: ' + SerAddr + ':' + IntToStr(ServerPort) + #13#10;
    If IsProxy Then Header := Header + 'Proxy-Connection: Keep-Alive' + #13#10 Else Header := Header + 'Connection: Keep-Alive' + #13#10;
    Header := Header + #13#10;
    CS.Socket.SendText(Header);
    //返回待下载文件大小.
    Reclen := 0;
    While CS.Active = true Do
    Begin
      If IsStop = true Then Break;
      Cmd := SocketRec(CS.Socket, 60 * 1000);
      If Pos(LowerCase('Content-Range:'), LowerCase(Cmd)) = 1 Then IsRec := true;
      If Pos(LowerCase('Content-Length: '), LowerCase(Cmd)) = 1 Then Reclen := StrToInt(Trim(Copy(Cmd, Length('Content-Length: ') + 1, Length(Cmd))));
      If Cmd = #13#10 Then Break;
      application.ProcessMessages;
    End;
    //跟着 开始接收服务器发过来的文件数据..
    Real_Reclen := 0;
    While CS.Active = true Do
    Begin  //判断是否下载完成
      If IsStop = true Then Break;
      If IsRec = false Then Break;
      If FileSize(FF) >= Total Then
      Begin
        result := true;
        Break;
      End;
      //接收文件数据
      ZeroMemory(@Buf, SizeOf(Buf));
      Rec := CS.Socket.ReceiveBuf(Buf, SizeOf(Buf));
  //判断是否下载完成
      If Real_Reclen >= Reclen Then
      Begin
        //文件已经下载完毕
        result := true;
        Break;
      End;
  //判断是否下载完成
      If DownPos = Reclen Then
      Begin
        //文件已经下载完毕
        result := true;
        Break;
      End;
//写入到文件
      BlockWrite(FF, Buf, Rec);
      Real_Reclen := Real_Reclen + Rec;

      //显示下载进度
      Progress(Real_Reclen, Reclen);

      application.ProcessMessages;
    End;
    CloseFile(FF);
    CS.Active := false;
  Except
    CloseFile(FF);
    result := false;
  End;
End;

出0入8汤圆

发表于 2015-3-24 20:59:45 来自手机 | 显示全部楼层
所谓http就是字符串拼接而已

出0入4汤圆

 楼主| 发表于 2015-3-24 21:03:35 | 显示全部楼层
谢谢大家,我好好研究一下

出0入4汤圆

 楼主| 发表于 2015-3-24 21:58:32 | 显示全部楼层
看到了,1460+1460+1460+966=5326 但是这几个包是在哪里发的呢,抓包工具看不到吗?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2015-3-24 22:11:00 | 显示全部楼层
billtian 发表于 2015-3-24 21:58
看到了,1460+1460+1460+966=5326 但是这几个包是在哪里发的呢,抓包工具看不到吗? ...

就是TCP Socket

出0入4汤圆

 楼主| 发表于 2015-3-24 22:36:52 | 显示全部楼层

抓包那个时间我怎么总看着是反的?发送数据包时间靠前啊,但是显然又不合理,怪了

出0入0汤圆

发表于 2015-3-26 00:14:28 | 显示全部楼层
需要能力较强的嵌入式开发人员和PC平台程序员,图像处理方向

出0入4汤圆

 楼主| 发表于 2015-3-27 15:05:35 | 显示全部楼层
前2天有位朋友给贴了一段代码,我当时没仔细看,能在帮忙发一下吗?谢谢了!

出0入0汤圆

发表于 2015-3-27 17:30:30 | 显示全部楼层
看到使用WireShark抓包了。

出0入0汤圆

发表于 2016-5-26 10:03:16 | 显示全部楼层
yeelink不错

出0入99汤圆

发表于 2016-6-4 08:31:42 | 显示全部楼层

yeelink 太难了,都是json,执行操作还慢,我发现了个比较好玩的,fuhome,就是简单的协议,响应速度比yelink快, ,不过最近准备用w5500搞的,enc28j60太麻烦了,协议栈一大堆
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 19:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表