C#中的HttpWebRequest底层是如何实现的? yeelink上传图片
用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字节 本帖最后由 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 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; 所谓http就是字符串拼接而已 谢谢大家,我好好研究一下 看到了,1460+1460+1460+966=5326 但是这几个包是在哪里发的呢,抓包工具看不到吗? billtian 发表于 2015-3-24 21:58
看到了,1460+1460+1460+966=5326 但是这几个包是在哪里发的呢,抓包工具看不到吗? ...
就是TCP Socket hyz_avr 发表于 2015-3-24 22:11
就是TCP Socket
抓包那个时间我怎么总看着是反的?发送数据包时间靠前啊,但是显然又不合理,怪了 需要能力较强的嵌入式开发人员和PC平台程序员,图像处理方向 前2天有位朋友给贴了一段代码,我当时没仔细看,能在帮忙发一下吗?谢谢了! 看到使用WireShark抓包了。 yeelink不错 wazhiyi 发表于 2016-5-26 10:03
yeelink不错
yeelink 太难了,都是json,执行操作还慢,我发现了个比较好玩的,fuhome,就是简单的协议,响应速度比yelink快,{:lol:} ,不过最近准备用w5500搞的,enc28j60太麻烦了,协议栈一大堆{:funk:}
页:
[1]