我使用HttpListener来搭建一个Http服务器时,客户端使用SIlverlight 发送一个Post请求,是一串大约1.5M的Json,服务端这边的Http Header的Content-Length的长度是正确的,但是使用Read读取的时候就不对了,少了一部分,我确认发送json是没有问题的,麻烦帮我看下是哪个环节出了问题呢?不胜感激,下面是部分服务端的接收代码问题代码:
private void GetContextCallBack(IAsyncResult ar)
        {
            try
            {
                HttpListener listener = ar.AsyncState as HttpListener;                ClientUser clientUser;
                
                HttpListenerContext context = listener.EndGetContext(ar);
                
                listener.BeginGetContext(new AsyncCallback(GetContextCallBack),listener);                if (context.Request.HttpMethod.ToLower().ToString() == "get")
                {
                    //获取授权文件的XML内容
                    string content = new AuthorizationFile().GetClientaccesspolicy(context.Request.RawUrl.ToString());                    //返回授权xml
                    if (content == "")
                    {
                        Console.WriteLine("警告:获取跨域授权文件失败,服务器拒接返回数据。\t" + DateTime.Now.ToString());
                    }
                    else
                    {
                        //开始响应给客户端跨域授权
                        HttpListenerResponse response = context.Response;
                        //返回类型为XML
                        response.ContentType = "text/xml";
                        //为UTF-8编码
                        response.ContentEncoding = Encoding.UTF8;                        using (StreamWriter sw = new StreamWriter(response.OutputStream))
                        {
                            sw.Write(content);
                            sw.Flush();
                            Console.WriteLine("响应客户端跨域请求\t" + DateTime.Now.ToString());
                        }
                    }
                }
                else if (context.Request.HttpMethod.ToLower().ToString() == "post")
                {
                    NameValueCollection head = context.Request.Headers;
                    //字节长度
                    string strLength = head.GetValues("Content-Length")[0];                    //读取客户端发送过来的数据
                    using (Stream inputStream = context.Request.InputStream)
                    {
                        long logLength = Convert.ToInt64(strLength);                        byte[] buffer = new byte[logLength];
                        //读取用户发送过来的正文
                        int jsonLength = inputStream.Read(buffer, 0, buffer.Length);                        if (jsonLength <= 0) return;                        //将其转为字符串
                        string json = Encoding.UTF8.GetString(buffer, 0, jsonLength);                        int length = json.Length;                        clientUser = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientUser>(json);
                        //验证数据库
                        Database db = new Database();                        bool? loginState = null;                        bool isEditor = false;                        //执行结果
                        STATE state = STATE.UNKNOWN;                        ResponsePackage responsePackage = new ResponsePackage();                        ClientUser requestData = null;                        //判断行为
                        switch (clientUser.type)
                        {
                            //登录
                            case ConnectType.LOGIN:
                                {
                                    Console.WriteLine("用户登录请求\t" + DateTime.Now.ToString());                                    loginState = db.Login(clientUser,out isEditor);                                    state = (bool)loginState ? STATE.LoginSuccess : STATE.LoginFail;

解决方案 »

  1.   

    Stream.Read从来就没有保证过会把缓冲区填满。
    因此原理上你要自己判断接续。for(int offset = 0; offset < buffer.Length; )
    {
       int received = inputStream.Read(buffer, offset, buffer.Length - offset);
       if (received == 0) throw ...   offset += received;
    }当然也可以用StreamReader来简化代码:
    using (Stream inputStream = context.Request.InputStream)
    using (StreamReader reader = new StreamReader(inputStream))
    {
       string json = reader.ReadToEnd();
    }
      

  2.   

    是这样的,我已经解决了,使用的ReadToEnd(); 感谢你的回答
      

  3.   

    你好,今天在做C#Http服务器,在网上找了很多例子,很多都是客户端连接的时候异常,请问一下可以提供一下你的例程吗