为啥我的 Windows CE 设备无法成功调用服务器的 REST 方法?
Posted
技术标签:
【中文标题】为啥我的 Windows CE 设备无法成功调用服务器的 REST 方法?【英文标题】:Why is my Windows CE device unable to successfully invoke my server's REST methods?为什么我的 Windows CE 设备无法成功调用服务器的 REST 方法? 【发布时间】:2015-02-17 17:25:03 【问题描述】:这是this question 的相关/某种后续,但包含越来越具体的信息。
我有一个 REST 应用程序在我的 PC 上运行。我需要从使用紧凑框架的手持 WindowsCE 设备调用服务器上的一些方法。
我可以通过 Postman 联系到服务器的方法,所以这样没有问题。在 Postman 中,我使用:
http://localhost:21609/api/inventory/sendXML/duckbill/platypus/bloo
...这样我就在我的服务器应用程序上到达了这个 REST 方法的断点:
[HttpPost]
[Route("api/inventory/sendxml/userId/pwd/filename")]
public async Task SendInventoryXML(String userId, String pwd, String fileName)
但是,尽管使用“PPP_PEER”是从手持设备联系 PC 的方式(127.0.0.1 无法运行,因为手持设备将其视为自身,并在尝试联系该设备时犯下了令人发指的自相残杀行为地址) - 从手持设备上工作的这个 TCP 代码可以看出:
string pingString = "PING|";
TcpClient client = new TcpClient("PPP_PEER", 7727);
try
try
Stream s = client.GetStream();
StreamReader sr = new StreamReader(s);
StreamWriter sw = new StreamWriter(s) AutoFlush = true ;
String response = String.Empty;
if (firstRecord)
sw.WriteLine(pingString);
. . .
...尝试使用 PPP_PEER 调用 REST 方法失败。
这是我用来尝试执行此操作的代码:
//HHSConsts
public static string BASE_REST_URL = "http://PPP_PEER:21609/api/";
. . .
//frmMain
private void SendInventories()
try
foreach (String tblname in listBoxWork.Items)
String xmlData = hhsdbutils.GetINVDataAsXMLFromTable(tblname, fileName);
String uri = String.Format("0inventory/sendXML/duckbill/platypus/1",
HHSConsts.BASE_REST_URL, fileName);
fileXferImp = HHSConsts.GetFileTransferMethodology();
fileXferImp.SendDataContentsAsXML(uri, xmlData, tblname);
. . .
// FileXferREST.cs
public void SendDataContentsAsXML(String destinationPath, String data, String fileName,
String siteNumber, bool firstRecord, bool lastRecord)
SendHTTPRequestNoCredentials(destinationPath, HttpMethods.POST, data, "application/xml");
public static HttpWebRequest SendHTTPRequestNoCredentials(string uri, HttpMethods method,
string data, string contentType)
WebRequest request = WebRequest.Create(uri);
try
request.Method = Enum.ToObject(typeof(HttpMethods), method).ToString();
request.ContentType = contentType;
((HttpWebRequest)request).Accept = contentType;
((HttpWebRequest)request).KeepAlive = false;
((HttpWebRequest)request).ProtocolVersion = HttpVersion.Version10;
if (method != HttpMethods.GET && method != HttpMethods.DELETE)
byte[] arrData = Encoding.UTF8.GetBytes(data);
request.ContentLength = arrData.Length;
using (Stream oS = request.GetRequestStream())
oS.Write(arrData, 0, arrData.Length);
else
request.ContentLength = 0;
catch (WebException webex)
HttpWebResponse hwr = (HttpWebResponse)webex.Response;
HttpStatusCode hsc = hwr.StatusCode;
String webExMsgAndStatusCode = String.Format("0 Status code == 1", webex.Message,
hsc.ToString());
ExceptionLoggingService.Instance.WriteLog(String.Format("From
FileXferREST.SendHTTPRequestNoCredentials: 0", webExMsgAndStatusCode));
return request as HttpWebRequest;
不抛出异常;它根本不起作用。
在尝试此调用时,我运行 rawcap 以使用以下命令行参数捕获通过网络发送的包:
rawcap 127.0.0.1 [fileName].pcap
然后我在 Wireshark 中打开 .pcap 文件,搜索“21609”并获取此 TCP 流:
...我添加了上面的屏幕截图以显示请求/响应的红色/蓝色,但这里是涉及端口 21609 的整个 rawcap/Wireshark 对话:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
POST /api//inventory/sendXML/duckbill/platypus/INV_3_20090307181658000.xml HTTP/1.0 内容类型:应用程序/xml 接受:应用程序/xml 连接:关闭 内容长度:388 主机:ppp_peer:21609
112209003343742SOME DESC2.2testVendorID]6161.51.995.58HTTP/1.1 404 未找到 缓存控制:私有 内容类型:文本/html;字符集=utf-8 服务器:Microsoft-IIS/8.0 X-SourceFiles: =?UTF-8?B?QzpccHJvamVjdFxnaXRcQ1N0b3JlXEhIUy5BUElcYXBpXGludmVudG9yeVxzZW5kWE1MXGR1Y2tiaWxsXHBsYXR5cHVzXElOVl8zXzIwMDkwMzA3MTgxNjU4MDAwLnhtbA==?= X-Powered-By: ASP.NET 日期:2014 年 12 月 18 日星期四 17:23:01 GMT 连接:关闭 内容长度:5016
IIS 8.0 详细错误 - 404.0 - 未找到
HTTP 错误 404.0 - 未找到
您要查找的资源已被删除、名称已更改或暂时不可用。 最可能的原因: .指定的目录或文件在 Web 服务器上不存在。 .URL 包含印刷错误。 .自定义过滤器或模块,例如作为 URLScan,限制对文件的访问。 你可以尝试的事情: .在 Web 服务器上创建内容。 .查看浏览器 URL。 .检查失败的请求跟踪日志并查看哪个模块正在调用 SetStatus。如需更多信息,请单击here。 详细错误信息: 模块 IIS Web 核心 通知 MapRequestHandler 处理程序 StaticFile 错误代码 0x80070002 请求的网址 http://ppp_peer:21609/api/inventory/sendXML/duckbill/platypus/INV_3_20090307181658000.xml 物理路径 C:\project\git\CStore\HHS.API\api\inventory\sendXML\duckbill\platypus\INV_3_20090307181658000.xml 登录方式 匿名 登录用户 匿名 请求跟踪目录 C:\Users\clay\Documents\IISExpress\TraceLogFiles\HHS.API 更多信息: 此错误表示服务器上不存在该文件或目录。创建文件或目录并再次尝试请求。View more information »
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
回顾一下,“PPP_PEER”确实可以作为手持设备描述/联系 PC 的一种方式(它与 TCP 代码一起使用),并且可以从另一个进程(例如 Postman)访问 REST 方法,但是尝试从手持设备使用 PPP_PEER 调用该方法失败,并出现“404.0 - Not Found”错误。
为什么?
更新
当我将“PPP_PEER”替换为PC的机器名时,错误从“404 - Not Found”变为“503 - Service Unavailable”:
但这有点像 rompecabeza,因为服务 显然是可用的,因为它正在运行并且当我从 Postman 调用它时它的断点被命中。
更新 2
现在这很奇怪:如果我使用完整的机器名称而不是“截断”名称,错误会回到 404 而不是 503:
所以如果我使用 PPP_PEER 作为主机名,我会得到 404;如果我使用 shannon2,我会得到 503;如果我使用 shannon2.sscs.ad,我再次得到 404。我应该将此归咎于 Tim Berners-Lee、Al Gore、Andy Warhol 还是其他人?
所以...这些是我尝试遵循 Eric Law 的第一个建议的结果;还有另外两个,但是:我将如何编辑 Host 标头 to 可能会有所不同?或者将其覆盖为什么?
【问题讨论】:
我的第一个假设是,虽然PPP_PEER
命中正确的 TCP/IP 端点,但该请求上的 Host
标头被拒绝,因为它不是服务器配置为响应的主机名。您可以尝试在 URL 中使用机器的公共主机名,或使用 Fiddler 编辑 Host
标头,甚至可能从客户端 API 手动覆盖它。
在您的 PC 上通过 Postman 调用 http://shannon2.sscs.ad:21609/api/inventory/sendXML/duckbill/platypus/bloo
是否有效? http 站点是否为 *:21609(即所有地址)绑定?
@ma499:是的,通过 Postman 工作。
@ma499:但是,如上所述,“如果我使用 shannon2.sscs.ad,我又会得到 404”
使用您的第一个 pcap 跟踪它与服务器的响应:Microsoft-IIS/8.0 很明显,该请求是针对您的 IIS 服务而不是您在 WebServer 中构建的 Visual Studio。
【参考方案1】:
似乎基本问题是试图访问在我的 PC 上本地运行的“服务器”应用程序(即使手持设备 != PC,它也是“某种”相同的东西,在时尚之后)。
现在服务器应用程序完全在网络上的另一台机器上运行,我可以点击它;虽然还不是完全没有例外,但可以看到here。
【讨论】:
以上是关于为啥我的 Windows CE 设备无法成功调用服务器的 REST 方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Windows CE 6.0 设备中配置 *** 客户端 [关闭]
为啥在我的 Web 服务中调用此方法时出现错误“无法将类型 'void' 隐式转换为 'string'?
为啥我会通过 Google Cloud To Device Messaging Service 为我的设备获取多个活动令牌?