C# HttpListener搭建服务在接收客户端发过来的POST请求时遇到的问题

chenyang373 2016-11-16 08:44:06
我使用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;
...全文
1738 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
yqc497578497 2018-09-19
  • 打赏
  • 举报
回复
你好,今天在做C#Http服务器,在网上找了很多例子,很多都是客户端连接的时候异常,请问一下可以提供一下你的例程吗
Forty2 2016-11-17
  • 打赏
  • 举报
回复
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(); }
chenyang373 2016-11-17
  • 打赏
  • 举报
回复
是这样的,我已经解决了,使用的ReadToEnd(); 感谢你的回答

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧