String WEB_SITE;
String FlagGB_Big;
int WEB_PORT;public ConnectionThread(Socket cl,int c,String GbSrcV,String Big5SrcV,String Gb2SrcV,String Big52SrcV,String WEB_SITEV,String FlagGB_BigV,int WEB_PORTV,String[] gb_1V,String[] gb_2V,String[] b5_1V,String[] b5_2V) throws IOException{
GbSrc=GbSrcV;
Big5Src=Big5SrcV;
Gb2Src=Gb2SrcV;
Big52Src=Big52SrcV;
WEB_SITE=WEB_SITEV;
FlagGB_Big=FlagGB_BigV;
WEB_PORT=WEB_PORTV;
gb_1=gb_1V;
gb_2=gb_2V;
b5_1=b5_1V;
b5_2=b5_2V;
wordGBLen=gb_1.length;
wordBig5Len=b5_1.length;client=cl;
counter=c;
}public void run() //线程体
{
try {
String destIP=client.getInetAddress().toString(); //客户机IP地址
int destport=client.getPort(); //客户机端口号
System.out.println("Connection "+counter+":connected to "+destIP+" on port "+destport+".");
PrintStream outstream=new PrintStream(client.getOutputStream());
BufferedReader instream=new BufferedReader(new InputStreamReader(client.getInputStream()));
String inline=instream.readLine(); //读取Web浏览器提交的请求信息
System.out.println("Received:"+inline);
int methodI=getrequest(inline);//获知客户(浏览器)请求方式
if (methodI>0) { //if the method GET or POST==如果客户请求方式为GET或POST,则处理,否则...
String filename=getfilename(inline);//据客户请求信息第一行(HTTP协议)得到请求的文件名
String fileExe=(filename.substring(filename.lastIndexOf('.')+1)).toLowerCase();//得到文件扩展名
//if not .txt==如果是二进制文件则不处理,关闭连接
if(   (fileExe.equalsIgnoreCase("gif"))||(fileExe.equalsIgnoreCase("exe"))||(fileExe.equalsIgnoreCase("swf"))||(fileExe.equalsIgnoreCase("jpg"))||(fileExe.equalsIgnoreCase("zip"))   ){
client.close();
}else{////////////////do with the data==处理得来的信息
String toString="";
URL WEB_URL;
String WEB_Path="";
String theURL="";
WEB_Path=WEB_SITE + "/" + filename;//得到请求文件服务器路径,以便向服务器请求//get the Path of URL.
int lastIdx=filename.lastIndexOf("/");
if (lastIdx>=0)
{
theURL=WEB_SITE+"/"+filename.substring(0,lastIdx);//得到文件服务器相对路径,以便处理HTML代码中的连接
}else{
theURL=WEB_SITE;
}//Read file from WEB_SERVER
char[] buffer = new char[4096]; 
int len;
WEB_URL=new URL(WEB_Path);
if (methodI==1){//if GET method==如果是GET方式请求,则直接用URL.openStream得到请求内容
BufferedReader inURL=new BufferedReader(new InputStreamReader(WEB_URL.openStream()));
                                       
            while((len = inURL.read(buffer)) != -1) { 
                String s = new String(buffer, 0, len); 
toString=toString+s;
}
inURL.close();
}else if(methodI==2){//if POST method==如果是POST方式请求,则...
//Read all which POST method need
String cmd="";
String cmdF="";
String oneLine="";while((oneLine = instream.readLine())!=null) {//读取头文件部份(HTTP协议相关)
cmdF=cmdF+oneLine+"\r\n";
if(oneLine.equalsIgnoreCase(""))break;
}int conLenIdx=cmdF.indexOf("Content-Length: ")+16;//据头文件信息可得到数据区长度,以及更改此长度后再发送到服务器(IIS)
int conRetIdx=cmdF.indexOf("\r\n",conLenIdx);//因为要对数据区进行转换,可能长度会变,故此。            while((len = instream.read(buffer))!=-1) { // ##here is a bug.==读取数据区,这儿有个BUG尚未解决,请往下看...
                String s = new String(buffer, 0, len); 
                cmd=cmd+s;
                break;//BUG在此,不管有没读完,都被中止,如果不这样,程序就死在这里了,不知道为什么。这个while语句应该是正确的但却不能够正常工作,下面还有类似情况。如果提交的表单内容比较少,一次就可以读完,所以没问题,但如果提交的数据内容比较多,那么就有问题了。
                //if (s.indexOf("\r\n\r\n")>=0)break;
}
// instream.close();cmd=URLDecoder.decode(cmd);//得到的数据区内容被浏览器encode过了,将其decode过来进行编码转换,即繁体->简体。另:这里也有BUG,大大的BUG^-^,如下
/*
关于此处BUG的说明:
在IE提交表单时会将数据Encoder后再提交给服务器,然后服务器应该是对其进行Decoder后再处理的。
Encoder时,对于一般的汉字应该是用两对"%"号后加两个字符表示一个汉字,比如繁体字的"我"应该是%A7%DA,繁体字的"用"则是%A5%CE,可是对于其它少部份汉字竟然会出现这种情况,如繁体字的"称"是Encoder后成了%26%2331216%3B,真是莫名其妙。然后对上边的数据,即"我"对应的%A7%DA,"用"对应的%A5%CE,"称"对应的%26%2331216%3B进行Decoder时,分别得到的数据是:и、ノ、称
对于前面两个汉字--"我"和"用",得到"и","ノ",这确实是繁体字(Big5码)中的"我"和"用",可"称"字竟然成了称这到底是怎么回事呢?应该如何解决呢?真把头都弄大了!*注:之所以提交的是繁体字,是因为网页是繁体版本的,即使在文本框中输入的是简体字,IE会自动将其转换成繁体后再提交。
*/int cmdBIdx=0,cmdEIdx=0;
String cmdTemp="",cmdChange="";
String oldcmd;/*
处理数据区,数据区格式为:
userName=и称ノ&userPWD=key123&userPWD2=key123&[email protected]&register= 猔 
应该以"="和"&"分段处理,但由于有时候提交的表单中有如以上所说的不正常的Encoder结果,所以得到此不正常的数据区,里边有个称影响数据区的正常处理,那其实就是"称"字。
直接得到的数据(即未经decode的)为:
userName=%A7%DA%26%2331216%3B%A5%CE&userPWD=key123&userPWD2=key123&[email protected]&register=+%AA%60+%A5U+
*/
while ((cmdBIdx=cmd.indexOf("=",cmdBIdx+1))!=-1){
cmdEIdx=cmd.indexOf("&",cmdBIdx);

if(cmdEIdx!=-1){
cmdChange=cmd.substring(cmdBIdx+1,cmdEIdx);//得到数据部份(即除"="号和"&"号外的数据),进行处理
oldcmd=cmdChange;//保存源始数据
cmdChange=new String(cmdChange.getBytes("GB2312"),"big5");//利用Java本身的转换内码功能进行首次处理
cmdChange=changeBig5Str(cmdChange,oldcmd);//用资源文件进行一一对应处理,具体请参见此函数。
cmdChange=changeWordsGB(cmdChange);//处理习惯用语,见函数
cmdChange=URLEncoder.encode(cmdChange);//再进行encode
cmd=cmd.substring(0,cmdBIdx+1)+cmdChange+cmd.substring(cmdEIdx);}else
{//遇到最后一个"=",处理方式同上
cmdChange=(cmd.substring(cmdBIdx+1));
oldcmd=cmdChange;
cmdChange=new String(cmdChange.getBytes("GB2312"),"big5");
cmdChange=changeBig5Str(cmdChange,oldcmd);
cmdChange=changeWordsGB(cmdChange);
cmdChange=URLEncoder.encode(cmdChange);
cmd=cmd.substring(0,cmdBIdx+1)+cmdChange;
}//end if
}//end whileint nLen=cmd.length();String cmdFF=cmdF.substring(0,conLenIdx);
String cmdFE=cmdF.substring(conRetIdx);
cmdF=cmdFF+nLen+cmdFE;//将处理后数据区长度加入头文件中cmd=inline+"\r\n"+cmdF+cmd+"\r\n\r\n";//完整的请求内容
//POST data to the Server and get feedback data.==将cmd以HTTP协议的POST方法提交给服务器,如(IIS),并得到IIS响应的数据。
BufferedOutputStream sender;
Socket client2=null;client2 = new Socket(InetAddress.getByName(WEB_URL.getHost()),WEB_PORT);
sender = new BufferedOutputStream(client2.getOutputStream());
sender.write(cmd.getBytes(),0,cmd.length());
sender.flush();

解决方案 »

  1.   

    BufferedReader receiver=new BufferedReader(new InputStreamReader(client2.getInputStream()));
    toString="";            while((len = receiver.read(buffer)) != -1) { // 这里也有个读取socket数据的BUG
                    String s = new String(buffer, 0, len);  
    toString=toString+s;
    if (s.indexOf("0\r\n\r\n")>=0)break;//此处由于while语句不能够正常结束,只能以此判断循环结束,因为一般服务器响应的数据结尾有"0\r\n\r\n"这样的一段内容,但如果HTML文件本身也有这样的内容的话,就会判断错误了。
    }
    receiver.close();
    }
    //至此已经得到了客户用GET或者POST方法请求的所有数据,而后进行HTML内容中连接的处理以及简体->繁体转换后发给客户(浏览器)//Change tag as <a href=...> <img src=...>==将HTML文件中所有要转换的连接文件,除js,css,txt外的连接变为正确的相对连接--加上正确的相对路径,以便浏览器再次向本程式请求而非直接向服务器请求,此处js文件本来也应该处理的,但太困难。
    if(!(  (fileExe.equalsIgnoreCase("js"))||(fileExe.equalsIgnoreCase("css"))||(fileExe.equalsIgnoreCase("txt"))    ))
    toString=ChangeLink(toString,theURL);//处理过程请参看函数/////////////////do with the toString and make it to GB<->Big5==以下简体->繁体转换
    //First:use System unicode.
    String oldString=toString;
    toString=new String(toString.getBytes("Big5"));//第一次利用Java内码转换功能进行转换//Second:use GB_Big5 source String to Change all of "?" in the string toString.
    toString=changeGBStr(toString,oldString);//利用资源文件及一一对应原理处理没有正常转换的"?"/////////////end of first changed
    /////////////change words==处理习惯用语
    toString=changeWordsBig5(toString);
    /////////////end of change wordsif(!(  (fileExe.equalsIgnoreCase("js"))||(fileExe.equalsIgnoreCase("css"))||(fileExe.equalsIgnoreCase("txt"))    ))
    toString=changeCharsetGB(toString);//如果是HTML文件或者asp,jsp,php文件等,将文件头部content='text/html; charset=gb2312'改为big5/////////////////output toString to client if (methodI==1){//如果是以GET方式请求的,加上头部
    outstream.println("HTTP/1.0 200 OK");
    outstream.println("MIME_version:1.0");
    outstream.println("Content_Type:text/html");
    outstream.println("Content_Length:"+toString.length()+2);
    outstream.println("");
    }
    //由于以POST方式请求的数据头部已经有的,不必要再加
    //将GET或者POST方式请求的数据反馈给客户(浏览器)
    outstream.println(toString);
    outstream.flush();
    System.out.println("posted!!!");
    } //end if not .txt
    } //if the method GET or POST//////////////waiting…………
    long m1=1; 
    while (m1<11100000) {m1++;} //延时
    client.close();
    } catch (IOException e) {
    System.out.println("Exception:"+e);
    } //end try} //end run()
    /* 获取请求类型是否为"GET"或"POST" */
    int getrequest(String s) { 
    if (s.length()>0)
    {
    String methodString=s.substring(0,3);
    if (methodString.equalsIgnoreCase("GET")) return 1;
    else if (methodString.equalsIgnoreCase("POS")) return 2;
    }
    return 0;
    }/* 获取要访问的文件名 */
    String getfilename(String s) {
    String f=s.substring(s.indexOf(' ')+1);
    f=f.substring(0,f.indexOf(' '));
    try {
    if (f.charAt(0)=='/')
    f=f.substring(1);
    } catch (StringIndexOutOfBoundsException e) {
    System.out.println("Exception:"+e);
    }
    return f;
    }//////////////do with the HTML String.==将HTML文件中连接,即以src、href、background等标签中的连接作必要的更改。
    public static String ChangeLink(String htmlString,String theURL){String rhtml=htmlString;
    int theIdx;theIdx=rhtml.indexOf(" src");
    if (theIdx>=0)
    {
    rhtml=FindIdx(rhtml,theIdx,theURL);//do with FindIdx()
    }
    while (theIdx>=0)
    {
    theIdx=rhtml.indexOf(" src",theIdx+5);
    if (theIdx>=0)
    {
    rhtml=FindIdx(rhtml,theIdx,theURL);//do with FindIdx()
    }
    }//srctheIdx=rhtml.indexOf(" background");
    if (theIdx>=0)
    {
    rhtml=FindIdx(rhtml,theIdx,theURL);//do with FindIdx()
    }
    while (theIdx>=0)
    {
    theIdx=rhtml.indexOf(" background",theIdx+5);
    if (theIdx>=0)
    {
    rhtml=FindIdx(rhtml,theIdx,theURL);//do with FindIdx()
    }
    }//backgroundtheIdx=rhtml.indexOf(" href");
    if (theIdx>=0)
    {
    rhtml=FindIdx(rhtml,theIdx,theURL);//do with FindIdx()
    }
    while (theIdx>=0)
    {
    theIdx=rhtml.indexOf(" href",theIdx+5);
    if (theIdx>=0)
    {
    rhtml=FindIdx(rhtml,theIdx,theURL);//do with FindIdx()
    }
    }//href
    return rhtml;
    }//end ChangeLinkpublic static String FindIdx(String htmlString,int theIdx,String theURL){
    String rhtml="";
    String shtml="";
    String c="'";
    String filePath;
    String fileType;
    String tailTemp;theURL=theURL+"/";int isLink,bIdx,eIdx,isHttp,isHttp2,isHttp3,dotIdx,firstTempIdx;
    isLink=htmlString.indexOf("<",theIdx-30);
    if (isLink<theIdx)
    {
    bIdx=htmlString.indexOf("=",theIdx);
    eIdx=htmlString.indexOf(">",theIdx);
    shtml=((htmlString.substring(bIdx+1,eIdx)).toLowerCase()).trim();
    isHttp=shtml.indexOf("http://");
    isHttp2=shtml.indexOf("javascript:");
    isHttp3=shtml.indexOf("mailto:");if ((isHttp==-1)&&(isHttp2==-1)&&(isHttp3==-1))//如果连接是以http://、javascript:或者mailto:开头的,不进行处理
    {//do with 
    char FirstChar=shtml.charAt(0);
    int havaChar=0;
    if ((FirstChar==c.charAt(0))||(FirstChar=='"'))//对于连接包含在单双引号内的处理
    {
    havaChar=1;//如有单双引号,则标志为1
    filePath=(shtml.substring(1)).trim();
    }else{
    havaChar=0;//如果没有引号,则标起为0,下边会用到
    filePath=shtml;
    }//end if
    firstTempIdx=filePath.indexOf("?");//连接中有问号的处理
    if (firstTempIdx>=0)
    {
    tailTemp=filePath.substring(firstTempIdx);
    filePath=filePath.substring(0,firstTempIdx);
    havaChar=0;
    }else{
    firstTempIdx=filePath.indexOf(" ");
    if (firstTempIdx>=0)
    {
    tailTemp=filePath.substring(firstTempIdx);
    filePath=filePath.substring(0,firstTempIdx);
    }else{
    tailTemp="";
    }
    }dotIdx=filePath.lastIndexOf('.') ;//fileTypefileType=filePath.substring(dotIdx+1);
    fileType=fileType.substring(0,fileType.length()-havaChar);if (!(    fileType.equalsIgnoreCase("html")||fileType.equalsIgnoreCase("htm")||fileType.equalsIgnoreCase("txt")||fileType.equalsIgnoreCase("css")||fileType.equalsIgnoreCase("asp")||fileType.equalsIgnoreCase("php")||fileType.equalsIgnoreCase("jsp")||fileType.equalsIgnoreCase("shtml")||fileType.equalsIgnoreCase("phtml")||fileType.equalsIgnoreCase("xhtml")||fileType.equalsIgnoreCase("js")||fileType.equalsIgnoreCase("xml")||fileType.equalsIgnoreCase("pl")
      

  2.   

    ))//如果连接文件为以上文件中的一种,则改变连接为相对连接,否则不改变
    {
    rhtml=htmlString.substring(0,bIdx+1)+FirstChar+theURL+filePath+tailTemp+htmlString.substring(eIdx);
    return rhtml;
    }else{
    return htmlString;
    }
    }else{
    return htmlString;
    }//if (isHttp==-1)
    }else{
    return htmlString;
    }//if (isLink<theIdx)
    }//end FindIdx()
    ////////////////////change one GB String to Big5 String
    public String changeGBStr(String toString,String oldString){
    int quIdx=0;
    char oldChar;
    quIdx=toString.indexOf('?');while (quIdx>=0)
    {
    oldChar=oldString.charAt(quIdx);if(!(oldChar=='?')){
    toString=changeGBChar(quIdx,oldChar,toString);
    }
    quIdx=toString.indexOf('?',quIdx+1);
    }return toString;
    }////////////////////change one Big5 String to GB String
    public String changeBig5Str(String toString,String oldString){
    int quIdx=0;
    char oldChar;
    quIdx=toString.indexOf('?');while (quIdx>=0)
    {
    oldChar=oldString.charAt(quIdx);if(!(oldChar=='?')){
    toString=changeBig5Char(quIdx,oldChar,toString);
    }
    quIdx=toString.indexOf('?',quIdx+1);
    }return toString;
    }
    ////////////////////change one GB char to Big5 char
    public String changeGBChar(int quIdx,char oldChar,String toString){
    int charIdx;
    String tempString;
    charIdx=GbSrc.indexOf(oldChar);if(charIdx>=0)
    {
    tempString=toString.substring(0,quIdx)+Big5Src.charAt(charIdx)+toString.substring(quIdx+1);
    }else
    {
    tempString=toString;
    }
    return tempString;
    }//end changeGBChar()////////////////////change one Big5 char to GB char
    public String changeBig5Char(int quIdx,char oldChar,String toString){
    int charIdx;
    String tempString;
    charIdx=Big52Src.indexOf(oldChar);if(charIdx>=0)
    {
    tempString=toString.substring(0,quIdx)+Gb2Src.charAt(charIdx)+toString.substring(quIdx+1);
    }else
    {
    tempString=toString;
    }
    return tempString;
    }//end changeBig5Char()
    ////////////////////change the HTML head to big5
    public String changeCharsetGB(String toString){
    int charsetIdx=toString.indexOf("2312");

    if (charsetIdx>=0){
    int tagIdx=toString.indexOf(">",charsetIdx);
    if (tagIdx-charsetIdx<10)
    toString=toString.substring(0,charsetIdx-2)+"big5  "+toString.substring(tagIdx-1);
    }

    return toString;
    }//end changeCharset()
    ////////////////////change the words in GBString.
    public String changeWordsGB(String GBString){
    //wordGBLen
    StringBuffer theStr=new StringBuffer (GBString);
    for(int i=0;i<wordGBLen;i++){
    String gb1=gb_1[i];
    int bIdx=0;
    while ((bIdx=GBString.indexOf(gb1,bIdx))>=0){
    theStr.replace(bIdx,bIdx+gb1.length(),gb_2[i]);
    bIdx=bIdx+1;
    }//while
    }//for
    return theStr.toString();
    }//end changeWordsGB()////////////////////change the words in big5String.
    public String changeWordsBig5(String big5String){
    //wordBig5Len
    StringBuffer theStr=new StringBuffer (big5String);
    for(int i=0;i<wordBig5Len;i++){
    String bi1=b5_1[i];
    int bIdx=0;
    while ((bIdx=big5String.indexOf(bi1,bIdx))>=0){
    theStr.replace(bIdx,bIdx+bi1.length(),b5_2[i]);
    bIdx=bIdx+1;
    }//while
    }//for
    return theStr.toString();
    }//end changeWordsBig5()
    }
      

  3.   

    寒楼上的。 
    --------------------------------
    String str2 = new String(str1.getBytes(),"BIG5");
    ------------------------------------------------
    可以测试一下这个例子。
    -----------------------------------------------
    String str1 = "纒ぱ";
    String str2 = new String(str1.getBytes(),"BIG5");
    String str3 = "龙的天空";
    System.out.println("------------------------------------");
    System.out.println("str1: " + str1);
    System.out.println("str2: " + str2);
    System.out.println("str3: " + str3);
    System.out.println("------------------------------------");