奇怪的HttpWebResponse错误:服务器协议违规

5

我尝试了所有方法,但仍然无法弄清楚为什么会出现这个错误。

背景: 我有一个用MonoTouch编写的iPad应用程序,并且我有一个在后台运行的线程,每15秒钟就要与服务器同步数据。这在线程的前几次迭代中都有效,但最终我会得到以下堆栈跟踪。

An exception occured: System.Net.WebException: Error getting response stream (ReadDone4): ServerProtocolViolation ---> System.FormatException: Input string was not in the correct format
  at System.UInt32.Parse (System.String s) [0x00010] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/UInt32.cs:405 
  at System.Net.WebConnection.GetResponse (System.Byte[] buffer, Int32 max) [0x000ba] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebConnection.cs:565 
  at System.Net.WebConnection.ReadDone (IAsyncResult result) [0x00095] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebConnection.cs:446 
  --- End of inner exception stack trace ---
  at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x0005e] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:819 
  at System.Net.HttpWebRequest.GetResponse () [0x0000e] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:827 
  at SyncService.REST.RestClient.Execute[IEnumerable`1] (SyncService.REST.RestRequest request) [0x00079] in /Users/Chris/Compass/SyncService/REST/RestClient.cs:42 

我正在与默认配置的IIS Web服务器通信。 这是我正在调用的方法:

public RestResponse<T> Execute<T>(RestRequest request){
    var restResponse = new RestResponse<T>();
    var serializer = new JavaScriptSerializer();
    var urlPath = _baseUrl + "/" + request.Resource;
    var httpRequest = (HttpWebRequest)HttpWebRequest.Create(new Uri(urlPath));

    httpRequest.Headers = request.Headers;
    Authenticator.Authenticate(httpRequest);

    httpRequest.Method = request.Method.ToString();
    if (request.Method == Method.POST)
        SetPostData(httpRequest, request);

    HttpWebResponse httpResponse = null;
    try{
        httpResponse = (HttpWebResponse) httpRequest.GetResponse();
        var reader = new StreamReader(httpResponse.GetResponseStream());
        var responseString = reader.ReadToEnd();
        reader.Close();
        restResponse.StatusCode = httpResponse.StatusCode;
        restResponse.Headers = httpResponse.Headers;
        restResponse.Data = serializer.Deserialize<T>(responseString);
        restResponse.ResponseStatus = ResponseStatus.Completed;
    } 
    catch(WebException e){

        restResponse.ResponseStatus = ResponseStatus.Error;
        restResponse.ErrorMessage = e.Message;
        restResponse.ErrorException = e;
        var webResponse = (HttpWebResponse) e.Response;
        if (webResponse != null){
            restResponse.StatusCode = webResponse.StatusCode;
            restResponse.Headers = webResponse.Headers;
        }
        if (restResponse.StatusCode != HttpStatusCode.NotModified)
            Console.WriteLine("An exception occured: " + e + "\r\n");
    }catch (Exception ex) {
        restResponse.ResponseStatus = ResponseStatus.Error;
        restResponse.ErrorMessage = ex.Message;
        restResponse.ErrorException = ex;
    }

    if (httpResponse != null) 
        httpResponse.Close();

    return restResponse;
}

请帮我,我不知道该怎么办。Google上没有任何信息。

在出现错误之前,我可以成功发送22个请求。

编辑 我已将问题缩小为服务器问题。这是asp.net MVC,只有当我向客户端发送304时才会出现异常。请参见服务器代码:

private void ServeHttpStatusCode() {
    Response.StatusCode = 304;
    Response.Status = "304 Not Modified";
    Response.StatusDescription = "The resource you are requesting has not been modified";
    Response.ContentType = "application/json";
    Response.Write("{\"Error\":\"The resource you are requesting has not been modified\"}");
    Response.End();
    Response.Close();
}

这意味着服务器的表现不太好 :) 您能否使用诸如 Fiddler 或 Ethereal 的 HTTP 分析工具查看原始响应? - Skurmedel
它工作了22次,然后停止。如果我杀死我的应用程序并重新开始...所有的请求都好了另外22次。你还认为它在服务器上吗? - Chris Kooken
2个回答

2
  • 客户端和服务器之间是否有代理?
  • 请求22次后总是失败吗?异常表示某些UInt32无法解析。
  • 服务器端是否出现异常?

没有代理,大约22个请求,也没有服务器异常。 - Chris Kooken
你能展示一下客户端代码吗?你可能会错误地在客户端重复使用某些东西。 - msms
1
考虑到异常和304状态码,最好的猜测是在这种情况下删除任何描述性文本。 - msms
1
移除 Response.Write。请参考 https://dev59.com/OXRB5IYBdhLWcg3wgXdV#602235。 - msms
1
这与内容类型有关,我将其设置为null,一切都好了。感谢您指引我正确的方向。 - Chris Kooken

1

如果有人在网上寻找关于这个问题的答案,我也曾经遇到过一些类似的问题。我正在编写一些功能测试,它们使用http PUT上传内容到Web服务器,然后立即使用http GET。

GET请求总是失败,并出现相同的Uint32解析错误。Windows版本没有问题。绝望之下,我使用了Thread.Sleep(20)在http请求之间插入一些延迟,这样就解决了错误。不确定为什么,但现在它可以工作了,对于我的测试来说已经足够好了,但对于生产环境来说可能还不够。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接