java socket 实现客户端、服务端(while、线程、线程池)

友情提示:SocketServer是服务端,SocketClient是客户端,先运行服务端再运行客户端,在客户端输入信息可在服务端返回,实现最简单的交互服务。另注意导包问题。

While 实现

socket 编程 C/S 结构

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

/**
 * 客户端
 */
public class SocketClient {
    public static void main(String[] args) {
        try {
            //初始化一个socket
            Socket socket = new Socket("127.0.0.1", 9999);
            //通过socket获取字符流
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //通过标准输入流获取字符流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
            while (true) {
                String str = bufferedReader.readLine();
                bufferedWriter.write(str);
                bufferedWriter.write("\n");
                bufferedWriter.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
/**
 * 服务端,while循环连续接受客户端信息
 */
public class SocketServer {
    public static void main(String[] args) {
        try {
            //初始化服务端socket并且绑定9999端口
            ServerSocket serverSocket = new ServerSocket(9999);
            //等待客户端的连接
            Socket socket = serverSocket.accept();
            //获取输入流,并且指定统一的编码格式
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
            //读取一行数据
            String str;
            //通过while循环不断读取信息,
            while ((str = bufferedReader.readLine()) != null) {
                //输出打印
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

如果你想拓展,可以看看下面的多线程实现

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class SocketClient1 {
    public static void main(String[] args) {
        try {
            //初始化一个socket
            Socket socket = new Socket("127.0.0.1", 9999);
            //通过socket获取字符流
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //通过标准输入流获取字符流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
            while (true) {
                String str = bufferedReader.readLine();
                bufferedWriter.write(str);
                bufferedWriter.write("\n");
                bufferedWriter.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 多线程下 socket 服务端
 *
 * @author NNroc
 * @date 2020/6/15 15:31
 */
public class SocketServer1 {
    public static void main(String[] args) throws IOException {
        //初始化服务端socket并且绑定9999端口
        ServerSocket serverSocket = new ServerSocket(9999);
        while (true) {
            //等待客户端的连接
            Socket socket = serverSocket.accept();
            //每当有一个客户端连接进来后,就启动一个单独的线程进行处理
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //获取输入流,并且指定统一的编码格式
                    BufferedReader bufferedReader = null;
                    try {
                        bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
                        //读取一行数据
                        String str;
                        //通过while循环不断读取信息
                        while ((str = bufferedReader.readLine()) != null) {
                            //输出打印
                            System.out.println("客户端" + str);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

线程

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 多线程下 socket 服务端
 * 对于大量数据来说,当线程创建出来后未回收,会大量占用资源
 *
 * @author NNroc
 * @date 2020/6/15 15:31
 */
public class SocketServer1 {
    public static void main(String[] args) throws IOException {
        //初始化服务端socket并且绑定9999端口
        ServerSocket serverSocket = new ServerSocket(9999);
        while (true) {
            //等待客户端的连接
            Socket socket = serverSocket.accept();
            //每当有一个客户端连接进来后,就启动一个单独的线程进行处理
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //获取输入流,并且指定统一的编码格式
                    BufferedReader bufferedReader = null;
                    try {
                        bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
                        //读取一行数据
                        String str;
                        //通过while循环不断读取信息
                        while ((str = bufferedReader.readLine()) != null) {
                            //输出打印
                            System.out.println("客户端" + str);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

线程池

服务端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程池下 socket 服务端,保证线程的复用
 *
 * @author NNroc
 * @date 2020/6/15 15:46
 */
public class SocketServer2 {
    public static void main(String[] args) throws IOException {
        //初始化服务端socket并且绑定9999端口
        ServerSocket serverSocket = new ServerSocket(9999);
        //创建一个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(100);
        while (true) {
            //等待客户端的连接
            Socket socket = serverSocket.accept();
            Runnable runnable = () -> {
                SocketAddress remoteSocketAddress = socket.getRemoteSocketAddress();
                BufferedReader bufferedReader = null;
                try {
                    bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
                    //读取一行数据
                    String str;
                    //通过while循环不断读取信息
                    while ((str = bufferedReader.readLine()).length() != 0) {
                        //输出打印
                        System.out.println("客户端" + remoteSocketAddress.toString() + "发送:" + str);
                    }
                } catch (SocketException e) {
                    System.out.println("客户端" + remoteSocketAddress.toString() + "断开连接");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            };
            executorService.submit(runnable);
        }
    }
}
客户端
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

/**
 * @author NNroc
 * @date 2020/6/15 15:35
 */
public class SocketClient1 {
    public static void main(String[] args) {
        try {
            //初始化一个socket
            Socket socket = new Socket("127.0.0.1", 9999);
            //通过socket获取字符流
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //通过标准输入流获取字符流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
            while (true) {
                String str = bufferedReader.readLine();
                if (str.equals("end")) {
                    break;
                }
                bufferedWriter.write(str);
                bufferedWriter.write("\n");
                bufferedWriter.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

设置需求

服务端
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * socket 指定长度发送数据
 * 在不定长通讯中,通常使用的方式时每次默认读取 8*1024长度的字节,若输入流中仍有数据,则再次读取,一直到输入流没有数据为止。
 * 但是如果发送数据过大时,发送方会对数据进行分包发送,这种情况下或导致接收方判断错误,误以为数据传输完成,因而接收不全。
 * 在这种情况下就会引出一些问题,诸如半包,粘包,分包等问题,
 *
 * @author NNroc
 * @date 2020/6/15 16:01
 */
public class SocketServer {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(9999);
            Socket client = serverSocket.accept();
            InputStream inputStream = client.getInputStream();
            DataInputStream dataInputStream = new DataInputStream(inputStream);
            while (true) {
                byte b = dataInputStream.readByte();
                int len = dataInputStream.readInt();
                byte[] data = new byte[len - 5];
                dataInputStream.readFully(data);
                String str = new String(data);
                System.out.println("获取的数据类型为:" + b);
                System.out.println("获取的数据长度为:" + len);
                System.out.println("获取的数据内容为:" + str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
客户端
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

/**
 * @author NNroc
 * @date 2020/6/15 16:09
 */
public class SocketClient1 {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1", 9999);
            OutputStream outputStream = socket.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
            Scanner scanner = new Scanner(System.in);
            if (scanner.hasNext()) {
                String str = scanner.next();
                int type = 1;
                byte[] data = str.getBytes();
                int len = data.length + 5;
                dataOutputStream.writeByte(type);
                dataOutputStream.writeInt(len);
                dataOutputStream.write(data);
                dataOutputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值