Socket基础通信功能实现

目录结构 

1.导入依赖JSONObject(内部是用Hashmap来存储的,所以也可以不用JSONObject)

        <!--将JSON转为字符串,将其他对象转为json。这里用来将socket传输的数据转换-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>

2.服务端代码(ForumServer)

public static void main(String[] args) {
        try {
            System.out.println("开始绑定ip");
            ServerSocket serverSocket = new ServerSocket(8181);
            System.out.println("ip绑定完成,等待连接");
            //每循环一次为一个请求连接,没有客户端请求连接时,阻塞循环,进入等待
            while (true){
               // 同一个socket,如果调用两次会报StreamCorruptedException,所以不要乱传socket
               Socket accept = serverSocket.accept();
               System.out.println("连接完成,开始获取字节数据");
               InputStream inputStream = accept.getInputStream();
               OutputStream outputStream = accept.getOutputStream();
               System.out.println("获取字节数据完成,创建写线程和读线程");
               new Thread(new Write(outputStream)).start();
               new Thread(new Read(inputStream)).start();
               System.out.println("创建写线程和读线程完成,可以读写");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 3.客户端代码(ForumClient)

public static void main(String[] args) {
       try {
           System.out.println("开始连接ip");
           Socket socket = new Socket("localhost",8181);
           System.out.println("ip连接完成,开始获取字节数据");
           InputStream inputStream = socket.getInputStream();
           OutputStream outputStream = socket.getOutputStream();
           System.out.println("获取字节数据完成,创建写线程和读线程");
           new Thread(new Write(outputStream)).start();
           new Thread(new Read(inputStream)).start();
           System.out.println("创建写线程和读线程完成,可以读写");
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

 4.读取消息(Read)

public class Read implements Runnable{
    private InputStream inputStream;
    public Read(InputStream inputStream){
        this.inputStream = inputStream;
    }
    @Override
    public void run() {
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(this.inputStream);
            while(true){
                System.out.println("读取消息:" + objectInputStream.readObject());
            }
            //闭流
            //objectInputStream.close();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

5.发送消息(Write)

public class Write implements Runnable{
    private OutputStream outputStream;
    public Write(OutputStream outputStream){
        this.outputStream = outputStream;
    }

    @Override
    public void run() {
        Scanner sc = new Scanner(System.in);
        ObjectOutputStream objectOutputStream = null;
        String str = null;
        try {
            objectOutputStream = new ObjectOutputStream(this.outputStream);

            while (true){
                JSONObject jsonObject = new JSONObject();
                System.out.println("发消息:");
                str = sc.next();
                jsonObject.put("消息",str);
                //发送消息
                objectOutputStream.writeObject(jsonObject);
                //刷新缓存
                objectOutputStream.flush();
            }
            //后续添加结束聊天--闭流
            //outputStream.close();
            //sc.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

6.结束


但是,因为发消息时传输的是HashMap,所以接收的消息也是JSON字符串。(这谁受得了)因此,我们对代码进行小小的改动一下(主要是对字节流部分的改动。当然了,根据具体需求,自己可以选择不同的格式)。

 

1.服务端代码(ForumServer)

public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8181);
            while(true){
                Socket accept = serverSocket.accept();
//----------------------------------华丽的分割线--------------------------------------------
//这部分代码与下面的客户端一样                
                //在这里进行一下改动
                InputStream inputStream = accept.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
                OutputStream outputStream = accept.getOutputStream();
                PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(outputStream, "GBK"), true);

                new Thread(new Read(bufferedReader)).start();
                new Thread(new Write(printWriter)).start();
//----------------------------------华丽的分割线--------------------------------------------
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2.客户端代码(ForumClient)

public static void main(String[] args) {
     try {
         Socket socket = new Socket("localhost", 8181);
//----------------------------------华丽的分割线--------------------------------------------
//这部分代码与服务端一样
         InputStream inputStream = socket.getInputStream();
         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
         OutputStream outputStream = socket.getOutputStream();
         PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(outputStream, "GBK"), true);
         new Thread(new Read(bufferedReader)).start();
         new Thread(new Write(printWriter)).start();
//----------------------------------华丽的分割线--------------------------------------------
     } catch (IOException e) {
         e.printStackTrace();
     }
 }

3.读取消息(Read)

public class Read implements Runnable{
    private BufferedReader bufferedReader;
    public Read(BufferedReader bufferedReader){
        this.bufferedReader = bufferedReader;
    }
    @Override
    public void run() {
        try {
            //从缓存中读取消息
            String str = null;
            while((str = bufferedReader.readLine()) != null){
                System.out.println("读取消息:" + str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4.发送消息(Write)

public class Write implements Runnable{
    private PrintWriter printWriter;
    public Write(PrintWriter printWriter){
        this.printWriter = printWriter;
    }

    @Override
    public void run() {
        Scanner sc = new Scanner(System.in);
        String str = null;
        while (true){
            System.out.println("发消息:");
            str = sc.next();
            //缓存中打印消息
            printWriter.println(str);
        }
        //后续添加结束聊天--闭流
    }

5.结束

后续可以根据自己需求增加心跳(在客户端增加,检测与服务器连接状态)、ip获取、群聊和结束聊天等功能。

 

*本人也是小白一枚,还请各位大佬指出不足之处。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值