java即时通讯socket案例

描述

实现多个客户端即时通讯的程序,服务器只起到了转发消息的作用。

核心代码
  • 服务端 CommunicationClient.java

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CommunicationClient {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ExecutorService es = Executors.newSingleThreadExecutor();
        try {
            Socket socket = new Socket("localhost", 8888);
            System.out.println("服务器连接成功");
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            // 向服务器发送消息
            System.out.println("请输入名称:");
            String name = scanner.nextLine();
            Message message = new Message(name, null, MessageType.TYPE_LOGIN, null);
            oos.writeObject(message);
//            message = (Message) ois.readObject();
//            System.out.println(message.getInfo() + message.getFrom());
            // 启动读取消息的现成
            es.execute(new ReadInfoThread(ois));

            // 通过主线程来发送消息
            boolean flag = true;
            while (flag) {
                message = new Message();
                System.out.println("TO:");
                message.setTo(scanner.nextLine());
                message.setFrom(name);
                message.setType(MessageType.TYPE_SEND);
                System.out.println("Info:");
                message.setInfo(scanner.nextLine());
                oos.writeObject(message);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class ReadInfoThread implements Runnable {

    private ObjectInputStream in;
    private boolean flag = true;

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public ReadInfoThread(ObjectInputStream in) {
        this.in = in;
    }

    @Override
    public void run() {


        try {
            while (flag) {
                Message message = (Message) in.readObject();
                System.out.println("[" + message.getFrom() + "]对我说:" + message.getInfo());
            }

            if (in != null) {
                in.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

  • 客户端 CommunicationClient.java

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CommunicationClient {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ExecutorService es = Executors.newSingleThreadExecutor();
        try {
            Socket socket = new Socket("localhost", 8888);
            System.out.println("服务器连接成功");
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            // 向服务器发送消息
            System.out.println("请输入名称:");
            String name = scanner.nextLine();
            Message message = new Message(name, null, MessageType.TYPE_LOGIN, null);
            oos.writeObject(message);
//            message = (Message) ois.readObject();
//            System.out.println(message.getInfo() + message.getFrom());
            // 启动读取消息的现成
            es.execute(new ReadInfoThread(ois));

            // 通过主线程来发送消息
            boolean flag = true;
            while (flag) {
                message = new Message();
                System.out.println("TO:");
                message.setTo(scanner.nextLine());
                message.setFrom(name);
                message.setType(MessageType.TYPE_SEND);
                System.out.println("Info:");
                message.setInfo(scanner.nextLine());
                oos.writeObject(message);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class ReadInfoThread implements Runnable {

    private ObjectInputStream in;
    private boolean flag = true;

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public ReadInfoThread(ObjectInputStream in) {
        this.in = in;
    }

    @Override
    public void run() {


        try {
            while (flag) {
                Message message = (Message) in.readObject();
                System.out.println("[" + message.getFrom() + "]对我说:" + message.getInfo());
            }

            if (in != null) {
                in.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}


  • 通用类 Message.java

import java.io.Serializable;

public class Message implements Serializable {
    private String from;
    private String to;
    private int type;
    private String info;

    public Message() {
    }

    public Message(String from, String to, int type, String info) {
        this.from = from;
        this.to = to;
        this.type = type;
        this.info = info;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}


  • 通用类 MessageType .java

public final class MessageType {
    // 登陆消息类型
    public static final int TYPE_LOGIN = 0x1;
    // 发送消息的类型
    public static final int TYPE_SEND = 0x2;
}

本聊天系统采用客户机/服务器(C/S)地模式来设计,是一个3层地C/S结构:数据库服务器→应用程序服务器端→应用程序客户端,其分层结构如下图所示。系统采用C/S结构,可以将任务合理分配到客户机端和服务器端,从而降低了系统的通讯开销。 1. 客户层 客户层也叫应用表示层,是应用程序地客户接口部分。给聊天工具设计一个客户层具用很多优点,这是因为客户层担负着用户与应用间地对话功能。它用于检查用户的输入数据,显示应用的输出数据。为了使用户能直观的进行操作,客户层需要使用接口。若聊天用户变更,系统只需改写显示控制和数据检查程序即可,而不影响其他两层。数据检查的内容限于数据的形式和值得范围,不包括有关业务的处理逻辑。 2. 服务层 服务层又叫功能层,相当于应用的本体,他是讲具体的业务出路逻辑编入程序中。例如,用户需要检索数据,系统没法将有关检索要求的信息一次性的传送给功能层:而用户登陆后,聊天登录信息是由功能层处理过的检索结果数据,他也是一次性传送给表示层的。在应用设计中,不许避免在表示层和功能层之间进行多次的数据交换,这就需要尽可能进行一次性的业务处理,达到优化整体设计的目的。 3. 数据层 数据层就是DBMS,本聊天工具使用了Microsoft公司的SQL Server2000能迅速执行大量的更新和检索,因此,从功能层传送到数据层的“要求”一般都使用SQL语言
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ITzhongzi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值