【奇怪】怀疑是编码的问题~
因为公司项目的奇怪需求,所以得自己写一个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




