Socket 客户端与服务端通信及控制台乱码问题解决

此片博客是根据慕课网Socket网络编程进阶与实战的学习记录。

简介

Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以较为方便的编写网络上数据的传递。在Java中,有专门的Socket类来处理用户的请求和响应。利用Socket类的方法,就可以实现两台计算机之间的通讯。

如果想了解Socket通讯原理及三次握手请移步。

Client客户端代码实现。

 public static void main(String[] args) throws IOException {
        Socket socket = new Socket();
        /*超时时间*/
        socket.setSoTimeout(3000);
        /*连接本地   端口2000  超时时间3000*/
        socket.connect(new InetSocketAddress(InetAddress.getLocalHost(), 2000), 3000);
        System.out.printf("已发起服务器连接,并进入后续流程");
        System.out.printf("客户端信息:" + socket.getLocalAddress() + "P:" + socket.getLocalPort());
        System.out.printf("服务器信息:" + socket.getInetAddress() + "P:" + socket.getPort());

        try {
            /*发送数据*/
            todo(socket);
        } catch (Exception e) {
            System.out.printf("异常关闭");
        }
        /*释放资源*/
        socket.close();
        System.out.println("客户端已退出~");
    }

    private static void todo(Socket client) throws IOException {
        /*键盘输入*/
        InputStream in = System.in;
        BufferedReader inpu = new BufferedReader(new InputStreamReader(in));
        /*得到socket输出流,转换成打印流*/
        OutputStream outputStream = client.getOutputStream();
        PrintStream socketPrintStream = new PrintStream(outputStream);

        /*得到Soclet输入流,转换为BufferedReader*/
        InputStream inputStream = client.getInputStream();
        BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(inputStream));


        boolean flag = true;
        do {
            /*键盘读取一行*/
            String str = inpu.readLine();
            /*发送到服务器*/
            socketPrintStream.println(str);
            /*从服务器读取一行*/
            String echo = socketBufferedReader.readLine();
            if ("bye".equalsIgnoreCase(echo)) {
               flag = false;
            }else{
                System.out.println(echo);
            }

        } while (flag);

        /*释放资源*/
        socketPrintStream.close();
        socketBufferedReader.close();

    }

Server服务端代码实现。

public static void main(String[] args) throws IOException {

        /**
         *  port:指定的端口号
         */
        ServerSocket serverSocket = new ServerSocket(2000);

        System.out.printf("服务器准备就绪~");
        System.out.printf("服务器信息:" +serverSocket.getInetAddress());


        /*等待客户端连接*/
        for (;;){
            /*套接字 得到客户端*/
            Socket client = serverSocket.accept();
            ClientHandler clientHandler = new ClientHandler(client);
            clientHandler.start();

        }
    }

    private  static class ClientHandler extends  Thread{
        private Socket socket;
        private boolean flag = true;
        ClientHandler(Socket socket){
            this.socket = socket;
        }

        @Override
        public void run() {
            super.run();
            System.out.println("新客户端连接:" +socket.getInetAddress()+" P:"+socket.getPort());

            try {
                PrintStream socketOutPut = new PrintStream(socket.getOutputStream());
                BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                do {
                      String str = socketInput.readLine();

                      if("bye".equalsIgnoreCase(str)){
                          flag =false;
                          /*回送*/
                          socketOutPut.println("bye");
                      }else{
                          /*打印数据长度,并回送*/
                          System.out.println(str);
//                          System.out.println(getEncoding("编码格式为:"+str));
                          socketOutPut.println("字符长度:"+str.length());
                      }
                }while (flag);
             }catch (Exception e){
                System.out.println("连接异常断开");
            }finally {
                /*连接关闭*/
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("客户端已退出:"+ socket.getInetAddress()+" P:"+socket.getPort());
            }
        }
    }

至此我们就实现了客户端和服务端的通信。

可以看到我们虽然实现了客户端和服务端的通信但是会有乱码这里提供一种解决方案 

方案来源

结尾追加

-Dfile.encoding=UTF-8

并且在你的builder.gradle中添加

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

这样就可以解决乱码的问题了!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 上实现 Socket 客户端服务端通信,可以通过 JavaSocket 编程实现。下面是一个简单的示例: 1. 服务端代码: ```java import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器已启动,等待客户端连接..."); while (true) { Socket socket = serverSocket.accept(); System.out.println("客户端连接:" + socket.getInetAddress()); Thread thread = new Thread(new ServerThread(socket)); thread.start(); } } } ``` 2. 服务端线程代码: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; public class ServerThread implements Runnable { private Socket socket; public ServerThread(Socket socket) { this.socket = socket; } @Override public void run() { try { BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String str; while ((str = reader.readLine()) != null) { System.out.println("客户端发送消息:" + str); } } catch (IOException e) { e.printStackTrace(); } } } ``` 3. 客户端代码: ```java import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class Client { public static void main(String[] args) throws UnknownHostException, IOException { Socket socket = new Socket("localhost", 8888); OutputStream outputStream = socket.getOutputStream(); outputStream.write("Hello Server".getBytes()); outputStream.flush(); socket.shutdownOutput(); socket.close(); } } ``` 在服务端启动后,等待客户端连接,当客户端连接后,开启一个线程处理客户端的请求。客户端通过 Socket 连接服务端,发送消息后关闭连接。 注意:以上代码仅为示例,没有进行异常处理等操作,实际使用时需要根据具体需求补充完整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值