简易TCPServer中文乱码问题

本人正处于初学者阶段,如有讲的不对的地方,望大牛指出!

参考了黑马的TCPServer基础案例,相信大家应该也会和我一样会遇到中文路径名的文件加载不出来的情况,接下来我们就来看看没解决之前的源码吧

package win.forme;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(6667);//构造服务器
        while (true){

            Socket iouse01 = ss.accept();//服务器保持监听状态
            new Thread(new Runnable(){//每加载一次图片创建一个线程
                @Override
                public void run() {
                    try {
                        InputStream ips = iouse01.getInputStream();//接收客户端请求的字节流

                        InputStreamReader ipsr = new InputStreamReader(ips);//字节转字符流

                        BufferedReader bis = new BufferedReader(ipsr);//将接收的字节流转换为字符流并缓冲

                        //处理请求行
                        String s = bis.readLine();
                        String[] arr = s.split(" ");
                        String htmlpath = arr[1].substring(1);

                        FileInputStream fis = new FileInputStream(htmlpath);//本地字节流读取硬盘字节数据
                        OutputStream ops = iouse01.getOutputStream();//获取网络输出流对象

                        //HTTP固定请求头代码
                        ops.write("HTTP/1.1 200 OK\r\n".getBytes());
                        ops.write("Content-Type:text/html\r\n".getBytes());
                        ops.write("\r\n".getBytes());

                        //读取本地目的文件并输出
                        byte[] bytes = new byte[1024];
                        int len;
                        while ((len = fis.read(bytes))!=-1){
                            ops.write(bytes,0,len);
                        }
                        fis.close();
                        iouse01.close();
                    }catch (IOException e){
                        e.printStackTrace();
                    }

                }
            }).start();

        }


    }
}

程序运行流程

服务器接收由浏览器请求的含有中文的路径的字节数据在经过InputStreamReader转换成字符流,再进行分割操作从而得到我们需要的请求路径htmlpath,最终服务器通过htmlpath找到本地的文件并响应浏览器的请求。

接下来是实践环节:打开ie浏览器,在地址栏输入;http://localhost:6667/html_heimalvyouwang.html

输入格式:协议 ://ip地址 :端口号/ 文件路径

没有中文的情况下是不会出现什么异常的,以下正常访问图片:

 接下来,是图片中含有中文情况下出现的异常情况:

 

 一水的异常信息。

原因是

当我们在debug时会神奇的发现,服务器在接收到含有中文的字节数据是一串乱码,以至于服务器在找本地文件时会发生找不到文件的情况。其实是我们访问的时候浏览器自动进行了url编码。

那如何解决呢?

其实呢,只需要在浏览器请行数据分割完成之后,将或得的htmlpath进行解码就能正常显示中文了,以下是修改之后的源码:

package win.forme;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;

public class TCPServer {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(6667);//构造服务器
        while (true){

            Socket iouse01 = ss.accept();//服务器保持监听状态
            new Thread(new Runnable(){//每加载一次图片创建一个线程
                @Override
                public void run() {
                    try {
                        InputStream ips = iouse01.getInputStream();//接收客户端请求的字节流

                        InputStreamReader ipsr = new InputStreamReader(ips);//字节转字符流

                        BufferedReader bis = new BufferedReader(ipsr);//将接收的字节流转换为字符流并缓冲

                        //处理请求行
                        String s = bis.readLine();
                        String[] arr = s.split(" ");
                        String url_htmlpath = arr[1].substring(1);
                        String utf8_htmlpath = URLDecoder.decode(url_htmlpath, "utf-8");
                        
                        FileInputStream fis = new FileInputStream(utf8_htmlpath);//本地字节流读取硬盘字节数据
                        OutputStream ops = iouse01.getOutputStream();//获取网络输出流对象

                        //HTTP固定请求头代码
                        ops.write("HTTP/1.1 200 OK\r\n".getBytes());
                        ops.write("Content-Type:text/html\r\n".getBytes());
                        ops.write("\r\n".getBytes());

                        //读取本地目的文件并输出
                        byte[] bytes = new byte[1024];
                        int len;
                        while ((len = fis.read(bytes))!=-1){
                            ops.write(bytes,0,len);
                        }
                        fis.close();
                        iouse01.close();
                    }catch (IOException e){
                        e.printStackTrace();
                    }

                }
            }).start();

        }


    }
}

希望我的文章能帮到正在遇到这个问题的小伙伴们!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值