CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  .NET技术 >  C#

【奇怪】怀疑是编码的问题~

楼主eglic(圪圪) (理由永远是谎言,信仰永远是自慰)2006-09-24 15:43:38 在 .NET技术 / C# 提问

因为公司项目的奇怪需求,所以得自己写一个Web服务器  
  现在访问正常了,但是,提交表单中如果内容是英文字符或者“两个或者两个以下”的中文字符  
  页面显示正常,如果表单中的中文字符超过三个就会出现页面输出不完整的情况  
   
  代码节选如下:  
  1、Socket部分略  
   
  2、读取浏览器的请求数据  
  byte[]   buff   =   new   byte[_Socket.Available];  
  _Socket.Receive(buff);  
  string   s   =   System.Text.Encoding.GetEncoding("GB2312").GetString(buff);  
   
  3、测试时,在字符串里组装的HTML  
                                  #region   构造HTML页面  
                                  string   os   =   @"<html>  
          <head>  
                  <title>RAPAgent   测试页面   by   eGlic</title>  
                  <style   type=""text/css"">  
                          *   {font-size:12px;}  
                  </style>  
          </head>  
          <body>  
                欢迎你,来自   <strong>##RemoteHost##</strong>   的   <u   style=""color:red"">##REQUEST_NAME##</u>   朋友!<br   />  
                <div   style=""border   :solid   1px   black;padding:10px;margin:20px;background-color:#F8F8F8;font-family:Courier   New;"">  
                          你的浏览器提交的数据是:<br   /><br   />  
                          ##Data##  
                  </div>  
                  <div   style=""border   :solid   1px   black;padding:10px;margin:20px;background-color:#F8F8F8;font-family:Courier   New;"">  
                  测试表单提交<br   />  
                  <form   action=""/Test.Asp""   method=""POST"">  
                          选择表单提交方式:<select   name=""PostMethod""   onchange=""JavaScript:this.form.method=this.value;"">  
                                  <option   value=""POST""   ##SEL1##>POST</option>  
                                  <option   value=""GET""   ##SEL2##>GET</option>  
                          </select><br   />  
                          请输入你的姓名:<input   type=""text""   name=""YourName""   value=""""   /><br   />  
                          <input   type=""submit""   name=""submit""   value=""提交表单""   />  
                  </form>  
                  </div>  
          </body>  
  </html>";  
                                  #endregion  
   
  4、分析浏览器提交的数据部分,因为HTTP头都是ASCII字符串,这部分代码略  
   
  5、分析表单数据  
              i)     先用\r\n\r\n分割字符串,这部分测试通过  
              ii)   解码用System.Web.HttpUtility.UrlDecode(s,   Encoding.GetEncoding("GB2312"));  
                      取得原始数据,这部分也是正常  
   
  6、把表单提交的数据显示在页面上,这部分也正常,但是…………  
  如果提交的出现的问题就是开头说的那样~  
  问题点数:200、回复次数:45Top

1 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-24 15:45:33 得分 0

如果提交的数据YourName是三个中文字符或者以上  
  最后输出的时候   <input   type=""submit""   name=""submit""   value=""提交表单""   />  
  这个无法完整输出,到value=""提交表单""的最后一个引号后面就结束了  
  整个页面的后面都不输出了Top

2 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-24 15:46:44 得分 0

补充:  
   
  替换字符串os里面的##标记是这样:  
  os   =   os.Replace("##RemoteHost##",   _Socket.RemoteEndPoint.ToString());  
  os   =   os.Replace("##Data##",   req.ToString().Replace("\r\n","<br   />\r\n"));  
   
  输出生成的HTML是这样:  
    byte[]   buff1   =   new   byte[Encoding.GetEncoding("GB2312").GetByteCount(s)];  
    buff1   =   Encoding.GetEncoding("GB2312").GetBytes(s);  
    _Socket.Send(buff1);  
    _Socket.Shutdown(SocketShutdown.Both);  
    _Socket.Close();  
  Top

3 楼viena(维也纳N02)回复于 2006-09-24 16:05:16 得分 0

不会,友情帮顶~Top

4 楼zhongkeruanjian(编程亮子)回复于 2006-09-24 16:09:18 得分 0

不是很明白你的问题,看了一下,是不是如果  
  os.Replace("##Data##",   req.ToString().Replace("\r\n","<br   />\r\n"));  
  Req这个String里有三个以上的中文字符就有问题?  
  Top

5 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-24 16:19:19 得分 0

关键不是这里,提交过来的变量  
  忘记贴上来了  
   
   
  os   =   os.Replace("##REQUEST_NAME##",   req.Fields["YourName"].Value);  
   
  这里不行  
   
  req.Fields["YourName"].Value   这个是表单字段的数据  
   
  如果这个里面超过两个中文字符整个页面就会被截断,但是它自己没有问题Top

6 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-24 16:39:51 得分 0

发现问题在哪儿了  
   
  编码的时候把中文当作一个字节长度  
  导致总长度被截断  
   
  但是没找到原因  
   
  继续顶Top

7 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-24 16:52:35 得分 0

在字符串后面补上一段空格就好了,让它吃去  
  可是,这不是最好的解决办法呀  
   
  os   +=   new   String('   ',Encoding.Default.GetByteCount(os)   -   os.Length);  
  Top

8 楼viena(维也纳N02)回复于 2006-09-24 17:01:18 得分 0

为什么要用UrlDecode?Top

9 楼viena(维也纳N02)回复于 2006-09-24 17:18:53 得分 0

//解码用System.Web.HttpUtility.UrlDecode(s,   Encoding.GetEncoding("GB2312"));  
  是否这里有问题?s是Unicode字符串吧,有必要加第二个参数吗?Top

10 楼Knight94(愚翁)回复于 2006-09-24 17:56:10 得分 0

to   编码的时候把中文当作一个字节长度  
  导致总长度被截断  
   
  你的问题应该是中文与英文字符混排,然后变化转换的问题。  
   
  其次,如果  
  System.Web.HttpUtility.UrlDecode(s,   Encoding.GetEncoding("GB2312"));  
  通过urldecode进行解码,那么建议你是用urlencode进行编码。Top

11 楼AFatPig(大肥猪)回复于 2006-09-24 18:37:45 得分 0

upTop

12 楼antoniusguo(anton)回复于 2006-09-24 21:25:55 得分 0

别的没看出来  
  byte[]   buff1   =   new   byte[Encoding.GetEncoding("GB2312").GetByteCount(s)];  
  buff1   =   Encoding.GetEncoding("GB2312").GetBytes(s);  
  这里第1行代码先省略Top

13 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-25 08:40:29 得分 0

星期一   up  
   
  还是没搞定Top

14 楼xingyaohua(邢跃华)回复于 2006-09-25 08:41:24 得分 0

帮upTop

15 楼zhoushp_cn()回复于 2006-09-25 08:51:34 得分 0

upup,     看半天也没明白Top

16 楼o07(四月·来也勿勿·去也冲冲)回复于 2006-09-25 09:41:06 得分 0

upup,     看半天也没明白  
  Top

17 楼www_123du_com(鼠·神·泪)回复于 2006-09-25 09:49:12 得分 0

呵呵Top

18 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-25 11:00:25 得分 0

郁闷,还没搞定Top

19 楼okokwukai(不老仙翁)回复于 2006-09-25 11:28:59 得分 0

从表现上看,应该是字符集的问题.Top

20 楼lizhizhe2000(武安侯)回复于 2006-09-25 11:33:57 得分 0

楼主强人,我帮不上了Top

21 楼liuxiaoyi666(MSMVP 小猪妹荣誉马甲之八卦兔子)回复于 2006-09-25 11:38:15 得分 0

你用socket侦听??  
   
   
  果然怪异......  
   
  socket如果有编码问题...直接用System.Text...编吧Top

22 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-25 12:43:49 得分 0

关键问题是:  
   
  System.Text.Encoding.Default.GetBytes()这里  
  字符串里面如果包含有中文字符,就会出现整个长度缩短  
  就像被截断一样,但是残留部分的编码没有问题,显示正常Top

23 楼liuxiaoyi666(MSMVP 小猪妹荣誉马甲之八卦兔子)回复于 2006-09-25 12:48:06 得分 0

不熟悉这个瞎说一下,以前我也碰上过,不记得咋解决的了  
   
  别人继续Top

24 楼reborter(www.xqblog.net我的博客)回复于 2006-09-25 13:07:16 得分 0

顶Top

25 楼antoniusguo(anton)回复于 2006-09-25 13:27:04 得分 0

关键问题是:  
   
  System.Text.Encoding.Default.GetBytes()这里  
  字符串里面如果包含有中文字符,就会出现整个长度缩短  
  就像被截断一样,但是残留部分的编码没有问题,显示正常  
   
   
  System.Text.Encoding.Default.GetBytes()  
  用不到这个方法的  
  System.Text.Encoding.GetEncoding("GB2312").GetString();  
  这个方法会测量长度,不需要再写了  
  问题可能是在  
  Http头是ascii  
  而本身却是GB2312  
  Top

26 楼antoniusguo(anton)回复于 2006-09-25 13:27:33 得分 0

有没有看过浏览器发出的请求是什么Top

27 楼antoniusguo(anton)回复于 2006-09-25 13:29:00 得分 0

在你发出响应的时候Content-Type里最好是有CharSet=GB2312  
  怀疑IE在请求的时候就先测你的CharSet,然后再按照这个CharSet发出响应的请求Top

28 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-25 13:29:55 得分 0

问题可能是在  
  Http头是ascii  
  而本身却是GB2312  
   
  ==================  
  恩,有可能,怎么解决?Top

29 楼myminimouse(坚决不用baidu)回复于 2006-09-25 13:58:19 得分 0

帮顶~Top

30 楼antoniusguo(anton)回复于 2006-09-25 14:07:25 得分 0

GB2312对us-ascii兼容可以全部GB2312取(不敢确定,但是用过几次),或者也可以分出来截取Top

31 楼antoniusguo(anton)回复于 2006-09-25 14:13:15 得分 0

或者去找个HttpServer的示例来看看就很清楚了Top

32 楼zhoufoxcn(周公)回复于 2006-09-25 14:22:29 得分 0

你在web.config里设置一下吧。  
          <globalization    
                          requestEncoding="gb2312"    
                          responseEncoding="utf-8"    
        />Top

33 楼hdt(倦怠)回复于 2006-09-25 14:28:35 得分 0

HttpUtility.HtmlEncodeTop

34 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-25 14:32:46 得分 0

…………我这个是WinForm应用程序  
   
  不是ASP.Net~~~~~~~~~~~~~~~~~Top

35 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-25 14:33:14 得分 0

和HTML没有关系  
   
  输入输出都是纯文本,至于内容是什么,没有任何关系Top

36 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-25 14:37:33 得分 0

HttpUtility.HtmlEncode   这个是肯定用不上的  
   
  -------------------------------------  
  System.Web.HttpUtility.UrlDecode(s,   Encoding.GetEncoding("GB2312"));  
  通过urldecode进行解码,那么建议你是用urlencode进行编码。  
   
  这个也没什么道理~因为URLEncode是浏览器自动完成的,我的服务器端无法控制  
  也不需要  
   
  ----------------------------------------  
  如同   antoniusguo(anton)     所说  
  所有问题集中在  
  用Socket发送一个中英文混合字符串的问题上  
  到底该用什么编码给他转换成字节数组?  
   
  PS:  
  以前我一直用.Net   2003,从来没遇到过这种问题  
  公司要求用.Net   2005   却碰到这等怪事~~Top

37 楼zhongkeruanjian(编程亮子)回复于 2006-09-25 14:47:42 得分 0

问题到了这份上,看来是Framework版本的问题。那除非你把你的源程序搞出来,不然难有人知道。Top

38 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-25 15:06:52 得分 0

郁闷~  
   
  我来写一个测试的东东Top

39 楼antoniusguo(anton)回复于 2006-09-25 15:40:09 得分 200

不会的,Socket,Encoding这些类我也一直在用,不过我做的不是Web   Server  
  请再仔细检查一次  
   
  用Socket发送一个中英文混合字符串的问题上  
  到底该用什么编码给他转换成字节数组?  
   
  编码应该是一样的都是GB2312(这里是指你的WebServer所用的CharSet)  
  除了Http头应该用ASCII(标准这么说的)  
  所以我写请求基本上这么写的  
  System.Text.Encoding   headEncoding   =   System.Text.Encoding.ASCII;  
  System.Text.Encoding   bodyEncoding   =   System.Text.Encoding.GetEncoding("GB2312");  
   
  System.Byte[]   responseHeader   =   headEncoding.GetBytes(strHeader);  
  System.Byte[]   responseBody   =   bodyEncoding.GetBytes(strBody);  
  System.Byte[]   response   =   new   System.Byte[responseHeader.Length   +   responseBody.Length];  
  System.Buffer.BlockCopy(responseHeader,   0,   response,   0,   responseHeader.Length);  
  System.Buffer.BlockCopy(responseBody,   0,   response,   responseHeader.Length,   responseBody.Length);  
   
  remoteSocket.Send(resposne);Top

40 楼antoniusguo(anton)回复于 2006-09-25 15:41:29 得分 0

最后这个方法可能有出入  
  remoteSocket.Send(resposne,   0,   response.Length);Top

41 楼antoniusguo(anton)回复于 2006-09-25 16:02:21 得分 0

所以我写请求基本上这么写的  
  这个不对,我是想说响应……Top

42 楼eglic(圪圪) (理由永远是谎言,信仰永远是自慰)回复于 2006-09-25 16:13:21 得分 0

_Headers["Content-Length"].Value   =   Encoding.Default.GetByteCount(s).ToString();  
  string   sHeaders   =   "HTTP/1.1   "   +   _Status   +   "\r\n";  
  sHeaders   +=   _Headers.ToString()+"\r\n";  
   
  byte   []   bHeaders   =   Encoding.ASCII.GetBytes(sHeaders);  
  byte[]   bBodies   =   Encoding.Default.GetBytes(s);  
   
  _Socket.Send(bHeaders,   0,   bHeaders.Length,   SocketFlags.None);  
  _Socket.Send(bBodies,   0,   bBodies.Length,   SocketFlags.None);  
   
  ======================================================  
  搞定~~  
   
  谢谢   antoniusguoTop

43 楼antoniusguo(anton)回复于 2006-09-25 16:15:50 得分 0

Encoding.Default.GetBytes(s);  
  不同系统的Default不一样的啊,注意安全Top

44 楼Csharp110(~泰山~)回复于 2006-09-25 18:08:05 得分 0

学习,帮顶!Top

45 楼www_123du_com(鼠·神·泪)回复于 2006-09-25 19:55:54 得分 0

string   s   =   System.Text.Encoding.GetEncoding("GB2312").GetString(buff);  
   
  ---->  
   
  System.Text.Encoding.GetEncoding("GB2312").GetDecoder()....  
   
  //对流进行编码解码由于可能存在碎片现象,请使用Encoding.GetDecoder和GetEncoder方法获取编码解码器对其进行操作,Decoder和Encoder都会记录本次留下的碎片,第二次继续使用。  
   
  //不知你是不是这个原因。Top

相关问题

关键词

得分解答快速导航

  • 帖主:eglic
  • antoniusguo

相关链接

  • CSDN .NET频道
  • .NET类图书
  • C#类图书
  • .NET类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo