Java网络编程实现多线程聊天

 更新时间:2021年07月04日 10:24:19   作者:大唐雨夜  
这篇文章主要为大家详细介绍了Java网络编程实现多线程聊天,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Java网络编程实现多线程聊天的具体代码,供大家参考,具体内容如下

聊天程序如果是单线程,会导致没人只能说一句,并且说了以后,必须等到另一个人的回复,才能说第二句。收发都在主线程中,不能同时进行。

解决方法:

将收发放到两个不同的线程

1. SendThread 发送消息线程
2. RecieveThread 接受消息线程
3. Server一旦接受到连接,就启动收发两个线程
4. Client 一旦建立了连接,就启动收发两个线程

多线程聊天

1 SendThread

package socket;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class SendThread extends Thread {
    private Socket s;
    public SendThread(Socket s) {
        this.s = s;
    }
    @Override
    public void run() {
        try {
            OutputStream os = s.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);
            while(true){
                Scanner sc = new Scanner(System.in);
                String str = sc.next();
                dos.writeUTF(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2 RecieveThread

package socket;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class RecieveThread extends Thread {
    private Socket s;
    public RecieveThread(Socket s) {
        this.s = s;
    }
    @Override
    public void run() {
        InputStream is = null;
        try {
            is = s.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while(true){
                String msg = dis.readUTF();
                System.out.println(msg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

3 Server

package socket;

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

public class Server {
    public static void main(String[] args) {
        try {
            ServerSocket ss = new ServerSocket(8888);
            System.out.println("监听端口号:8888");
            Socket s = ss.accept();

            new SendThread(s).start();
            new RecieveThread(s).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4 Client

package socket;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
    public static void main(String[] args) {
        try {
            Socket s = new Socket("127.0.0.1", 8888);

            new SendThread(s).start();
            new RecieveThread(s).start();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

简单对话框

Server

package socket;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class GUIServer {

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

        JFrame f = new JFrame();
        f.setTitle("server");

        f.setSize(400, 300);
        f.setLocation(100, 200);
        f.setLayout(null);

        JButton b = new JButton("send");
        b.setBounds(10, 10, 80, 30);
        f.add(b);

        final JTextField tf = new JTextField();
        tf.setBounds(10, 110, 80, 30);
        f.add(tf);

        final JTextArea ta = new JTextArea();
        ta.setBounds(110,10, 200, 300);
        f.add(ta);

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);

        ServerSocket ss = new ServerSocket(8888);

        System.out.println("listenning on port:8888");
        final Socket s =  ss.accept();        
        new Thread() {
            public void run() {
                while (true) {
                    try {
                        DataInputStream dis = new DataInputStream(
                                s.getInputStream());
                        String text = dis.readUTF();
                        ta.append(text+"\r\n");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }
        }.start();

        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                String text = tf.getText();
                ta.append(text+"\r\n");

                try {
                    DataOutputStream dos = new DataOutputStream(
                            s.getOutputStream());
                    dos.writeUTF(text);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });

    }
}

Client

package socket;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class GUIClient {

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

        JFrame f = new JFrame();
        f.setTitle("client");

        f.setSize(400, 300);
        f.setLocation(600, 200);
        f.setLayout(null);

        JButton b = new JButton("send");
        b.setBounds(10, 10, 80, 30);
        f.add(b);

        final JTextField tf = new JTextField();
        tf.setBounds(10, 110, 80, 30);
        f.add(tf);

        final JTextArea ta = new JTextArea();
        ta.setBounds(110,10, 200, 300);
        f.add(ta);

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);

        final Socket s = new Socket("127.0.0.1", 8888);

        new Thread() {
            public void run() {
                while (true) {
                    try {
                        DataInputStream dis = new DataInputStream(
                                s.getInputStream());
                        String text = dis.readUTF();
                        ta.append(text+"\r\n");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }
        }.start();

        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                String text = tf.getText();
                ta.append(text+"\r\n");

                try {
                    DataOutputStream dos = new DataOutputStream(
                            s.getOutputStream());
                    dos.writeUTF(text);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });

    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • maven springboot如何将jar包打包到指定目录

    maven springboot如何将jar包打包到指定目录

    这篇文章主要介绍了maven springboot如何将jar包打包到指定目录,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • MyBatis-Plus通过version机制实现乐观锁的思路

    MyBatis-Plus通过version机制实现乐观锁的思路

    version机制的核心思想就是,假设发生并发冲突的几率很低,只有当更新数据的时候采取检查是否有冲突,而判断是否有冲突的依据就是version的值是否被改变了,这篇文章主要介绍了MyBatis-Plus通过version机制实现乐观锁的思路,需要的朋友可以参考下
    2021-09-09
  • Java如何获取JSON中某个对象的值

    Java如何获取JSON中某个对象的值

    这篇文章主要介绍了Java如何获取JSON中某个对象的值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java 常量字符串过长的解决方法

    Java 常量字符串过长的解决方法

    这篇文章主要介绍了Java 常量字符串过长的解决方法,常量字符串过长会提示报错,下面我们就一起来了解一下解决方法
    2021-04-04
  • eclipse实现ElGamal数字签名

    eclipse实现ElGamal数字签名

    这篇文章主要为大家详细介绍了eclipse实现ElGamal数字签名,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • SpringBoot读取Resource目录下文件的四种方式总结

    SpringBoot读取Resource目录下文件的四种方式总结

    在Spring Boot项目中,经常需要获取resources目录下的文件,这些文件可以包括配置文件、模板文件、静态资源等,本文将介绍四种常用的方法来获取resources目录下的文件,需要的朋友可以参考下
    2023-08-08
  • Springmvc应用Mongodb分页实现

    Springmvc应用Mongodb分页实现

    这篇文章主要为大家详细介绍了Springmvc应用Mongodb分页实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Mybatis控制台打印Sql语句的实现代码

    Mybatis控制台打印Sql语句的实现代码

    MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架,下面给大家介绍Mybatis控制台打印Sql语句的实现代码,非常不错,感兴趣的朋友一起看下吧
    2016-07-07
  • Java调用Pytorch实现以图搜图功能

    Java调用Pytorch实现以图搜图功能

    这篇文章主要为大家详细介绍了Java如何调用Pytorch实现以图搜图功能,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
    2023-06-06
  • Eclipse快速添加get、set方法的操作技巧

    Eclipse快速添加get、set方法的操作技巧

    这篇文章主要介绍了Eclipse快速添加get、set方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-07-07

最新评论