我使用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;
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;
因此原理上你要自己判断接续。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();
}