Socket学习--网络通信系统

Socket–韩顺平简易网络通信系统

涉及技术

  1. 面向对象编程
  2. 网络编程
  3. 多线程
  4. IO流
  5. 集合
  6. 框架设计

实现功能

  1. 用户登录
  2. 拉取在线用户列表
  3. 无异常退出(客户端, 服务器端)
  4. 私聊
  5. 群发
  6. 发文件
  7. 服务器端推送消息

实现效果

1.主界面及用户登录

image-20220720204609673

2.拉取在线用户列表

登陆多个用户

image-20220720204943614

3.私聊

发送方

image-20220720205742448

接收方

image-20220720205754136

服务端显示

image-20220720210119710

4.群发消息

发送方

image-20220720210209441

接收者

image-20220720210303184

image-20220720210328688

服务器端显示

image-20220720210229462

5.发送文件

发送方

image-20220720210523192

接收方文件本地地址

image-20220720210741751

服务器端

image-20220720210641583

6.服务器推送消息

image-20220720211002543

image-20220720210934943

服务器端显示

image-20220720211022934

7.离线聊天发送文件

发送方

image-20220720211519048

接收方上线

image-20220720211615592

客户端代码

客户端结构总览

image-20220720212230049

QQView主界面
package com.wu.qqclient.view;

import com.wu.qqclient.service.FileClientService;
import com.wu.qqclient.service.MessageClientService;
import com.wu.qqclient.service.UserClientService;
import com.wu.qqclient.utils.Utility;

/**
 * 客户端的显示界面
 */
public class QQView {
   
    private boolean loop = true;//控制主菜单中循环
    private String key = "";
    private UserClientService userClientService = new UserClientService();//负责登陆,拉取用户列表,退出功能
    private MessageClientService messageClientService = new MessageClientService();//消息传输相关功能实现
    private FileClientService fileClientService = new FileClientService();

    //客户端主函数
    public static void main(String[] args) {
   
        new QQView().mainMenu();
        System.out.println("退出系统");
    }

    /**
     * 主菜单
     */
    private void mainMenu() {
   

        while (loop) {
   

            System.out.println("=============欢迎登录网络通信系统=============");
            System.out.println("\t\t\t 1 登录系统");
            System.out.println("\t\t\t 9 退出系统");
            System.out.print("请输入你的选择:");
            key = Utility.readString(1);

            switch (key) {
   
                //用户登录
                case "1":
                    System.out.print("请输入用户名: ");
                    String userId = Utility.readString(50);
                    System.out.print("请输入密  码: ");
                    String pwd = Utility.readString(20);
                    //检测用户名和密码
                    if (this.userClientService.checkUser(userId, pwd)) {
   
                        System.out.println("欢迎" + userId + "用户登录成功");
                        //二级菜单
                        while (loop) {
   
                            System.out.println("\n=============网络通信系统二级菜单(用户:" + userId + ")=============\"");
                            System.out.println("\t\t\t 1 显示在线用户列表");
                            System.out.println("\t\t\t 2 群发消息");
                            System.out.println("\t\t\t 3 私聊消息");
                            System.out.println("\t\t\t 4 发送文件");
                            System.out.println("\t\t\t 9 退出系统");
                            System.out.print("请输入你的选择: ");
                            key = Utility.readString(1);
                            switch (key) {
   
                                //拉取在线用户列表
                                case "1":
                                    userClientService.onlineFriendList();
                                    break;
                                //群发消息
                                case "2":
                                    System.out.print("输入群聊消息:");
                                    String info = Utility.readString(50);
                                    messageClientService.groupChat(info, userId);
                                    break;
                                //发送私聊消息
                                case "3":
                                    System.out.print("输入想要私聊的用户名(在线): ");
                                    String getterId = Utility.readString(50);
                                    System.out.print("请输入内容");
                                    String content = Utility.readString(100);
                                    messageClientService.privateChat(content, userId, getterId);
                                    break;
                                //发送文件
                                case "4":
                                    System.out.print("输入想要发送文件的用户名:");
                                    String fileGetterId = Utility.readString(50);
                                    System.out.print("输入想要传输的文件地址");
                                    String src = Utility.readString(50);
                                    fileClientService.sendFile(src, userId, fileGetterId);
                                    break;
                                //退出系统
                                case "9":
                                    userClientService.exitQQClient();
                                    break;
                            }
                        }
                    } else {
   
                        System.out.println("=============登  录  失  败=============");
                    }
                    break;
                case "9":
                    loop = false;
                    break;
            }
        }
    }


}



Service服务类
1.UserClientService用户请求处理类
package com.wu.qqclient.service;

import com.wu.qqcommon.Message;
import com.wu.qqcommon.MessageType;
import com.wu.qqcommon.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;

/**
 * 负责用户登陆,拉取在线用户列表,退出系统功能
 */
public class UserClientService {
   
    private User user = new User();
    private boolean flag = false;
    private Socket socket;

    /**
     * 检测用户名密码,成功登陆开启socket线程
     * @param userId 用户名
     * @param pwd 密码
     * @return T/F
     */
    public boolean checkUser(String userId, String pwd) {
   
        user.setUserId(userId);
        user.setPasswd(pwd);

        try {
   
            //以本机为服务器.端口为9999的socket对象
            socket = new Socket(InetAddress.getByName("127.0.0.1"), 9999);
            //得到输出流
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            //将user传输给服务器
            oos.writeObject(user);
            //socket输入流
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            //读取数据报
            Message ms = (Message)ois.readObject();
            //登录成功
            if (ms.getMesType().equals(MessageType.MESSAGE_LOGIN_SUCCED)) {
   
                //创建一个线程对象
                ClientConnectService clientConnectService = new ClientConnectService(socket);
                //开启线程
                clientConnectService.start();
                //将线程加入线程池中,以userId(用户名)为键值,线程对象为Value
                ManageClientConnectServiceThread.addClientConnectServiceThread(userId, clientConnectService);
                //成功登陆,返回值设为true
                flag = true;
            } else {
   
                //登录失败,关闭socket
                socket.close();
            }
        } catch (Exception e) {
   
            e.printStackTrace();
        }
        //返回值
        return flag;
    }

    /**
     * 拉取在线用户列表
     */
    public void onlineFriendList() {
   
        Message message = new Message();//创建一个数据报对象message
        message.setMesType(MessageType.MESSAGE_GET_ONLINE_FRIEND);//设置消息雷响
        message.setSender(user.getUserId());//设置发送用户信息

        try {
   
            //通过用户名得到线程池中对应线程,再通过该线程得到的socket对象get输出流
            ObjectOutputStream oos = new ObjectOutputStream(ManageClientConnectServiceThread.
                    getClientConnectServiceThread(this.user.getUserId()).getSocket().getOutputStream());
            //写入数据
            oos.writeObject(message);
        } catch (IOException var3) {
   
            var3.printStackTrace();
        }

    }

    /**
     * 退出客户端下线
     */
    public void exitQQClient() {
   
        Message message = new Message();
        message.setMesType(MessageType.MESSAGE_CLIENT_EXIT);//消息类型
        message.setSender(user.getUserId());//发送者信息

        try {
   
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(message);
            System.out.println("用户:"+user.getUserId()+"退出系统");
            //ManageClientConnectServiceThread.removeClientServiceThread(user.getUserId());
            System.exit(0);//退出
        } catch (IOException e) {
   
            e.printStackTrace();
        }

    }
}

2.ClientConnectService客户端连接线程类
package com.wu.qqclient.service;

import com.wu.qqcommon.Message;
import com.wu.qqcommon.MessageType;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.net.Socket;

/**
 * 客户端socket通信线程,监听接收并根据消息类型做出反馈
 */

public class ClientConnectService extends Thread {
   
    private Socket socket;
    //private ObjectInputStream ois = null;

    public ClientConnectService(Socket socket) {
   
        this.socket = socket;
    }

    //线程
    @Override
    public void run() {
   
        while (true) {
   
            try {
   
                //创建输入流
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                //读取对象
                Message message = (Message) ois.readObject();

                //拉取用户列表
                if (message.getMesType().equals(MessageType.MESSAGE_RET_ONLINE_FRIEND)) {
   
                    System.out.println("\n当前在线用户列表:");
                    String[] onlineUsers = message.getContent().split(" ");
                    for (String s : onlineUsers) {
   
                        System.out.println("用户: " + s);
                    }
                    //私聊消息
                } else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {
   
                    System.out.println("\n" + message.ge
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值