`

java io学习笔记2---结合一个基于socket的聊天室

阅读更多
  前面间学习了java io的编程,后来感觉光只是看这些收获甚微,于是就自己做了一个简单的聊天室。基于java socket的聊天室,实现了客户端,实现了群聊,私聊,发送表情,互相发送文件,查看聊天记录,以及一些相关的设置;服务器端实现了发送系统公告,以及踢人的功能。具体的代码,我上传在附件里面。


     首先,介绍一个系统的总体架构,基于c/s模式的java聊天室,采用socket编程,当然,传输数据,我采用的是tcp协议,在服务器端进行监听,每次加入一个新的用户,就开辟一个新的线程用于监听这个用户的动态。当然,这种方式可能不是很科学,但由于知识有限,只能简单的应用。
/**
     * 功能:启动服务器
     */
    public static void startServer() {
        try {
            server = new ServerSocket(port);
            flag = true;
            System.err.print("服务器已经启动,正在监听用户线程.....");
        } catch (Exception e) {
            System.out.println("异常");
            System.err.println(e);
        }
        while (flag) { // 死循环
            Socket socket = null;
            try {
                socket = server.accept();
                ServerThread cp = new ServerThread(socket); // 启动一个用户线程
                System.out.println("新进入一个用户");
                cp.setIndex(count + 1);
                Thread ct = new Thread(cp);
                ct.start();
                addConnection(socket, cp);
                count++;
            } catch (IOException e) {
                System.err.println(e);
                try {
                    socket.close();
                } catch (IOException e1) {

                    e1.printStackTrace();
                }
            }
        }
    }



    另外还有一个服务器新建的线程类,ServerThread 由于过长,就不粘贴了。ServerThread 是实现Runnable接口的,里面含有,线程的名称(我这里用的用户的昵称作为参数),线程的索引(也就是在用户列表中的位置),以及ip地址(为了实现俩个聊天用户发送文件),以及socket。


需要说明的我的整体思路

用户端能够进行登录,注册,以及其他一些功能,ServerThread用户监听用户发来的数据。我在这里采用的字符流来进行发送(开始的时候,我采用的是ObjectStream,后来发现这样的传输效率很低,而且经常容易出错,这里不知道为什么),所以后来我就采用了字符流来进行传输数据。

当然,java 是面向对象的思想,我还是将一些东西创建了实体类,如MessageModel



/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package chatroom.com.entity;
/**
 *
 * @author Administrator
 */
import java.io.Serializable;
import java.util.Date;

public class MessageModel{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private int id;
	private String fromWho;// 谁说的
	private String toWho;// 对谁说
	private String dongzuo;// 动作是什么
	private int biaoqing;// 表情是什么
	private String ziti;// 字体
	private String yanse;// 颜色
	private String daxiao;// 大小
	private String yangshi;// 样式

	private String content;// 内容
	private int isSiliao;// 是否私聊
	private Date sendTime;

        /**
         * 功能:将字符串转换后MessageModel对象
         * @param str
         * @return 
         */
	public static MessageModel getMsgByString(String str) {
		String rs[] = str.split("&");
		MessageModel msg = new MessageModel();
		msg.setFromWho(rs[1]);
		msg.setToWho(rs[2]);
		msg.setDongzuo(rs[3]);
		msg.setBiaoqing(Integer.parseInt(rs[4]));
		msg.setZiti(rs[5]);
		msg.setYanse(rs[6]);
		msg.setDaxiao(rs[7]);
		msg.setYangshi(rs[8]);
		msg.setContent(rs[9]);
		msg.setIsSiliao(Integer.parseInt(rs[10]));
		return msg;

	}

        /**
         * 功能:将MessageModel对象转换成字符串
         * @param msg
         * @return 
         */
	public static String getStringByMessage(MessageModel msg) {
		return msg.getFromWho() + "&" + msg.getToWho() + "&" + msg.getDongzuo()
				+ "&" + msg.getBiaoqing() + "&" + msg.getZiti() + "&"
				+ msg.getYanse() + "&" + msg.getDaxiao() + "&"
				+ msg.getYangshi() + "&" + msg.getContent() + "&"
				+ msg.getIsSiliao();
	}

	@Override
	public String toString() {
		return "MessageModel [id=" + id + ", fromWho=" + fromWho + ", toWho="
				+ toWho + ", dongzuo=" + dongzuo + ", biaoqing=" + biaoqing
				+ ", ziti=" + ziti + ", yanse=" + yanse + ", daxiao=" + daxiao
				+ ", yangshi=" + yangshi + ", content=" + content
				+ ", isSiliao=" + isSiliao + ", sendTime=" + sendTime + "]";
	}

还有一些setter,geter方法

}




另外,对于聊天记录的读写,我采用的是文件的操作,主要是按行写入文件,按行读取文件,这里,我稍微做了一些改动,能够实现分页读取聊天记录。

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package chatroom.com.util;

import chatroom.com.chatEvent.Chat;
import java.io.*;
import javax.swing.JTextPane;

/**
 *功能:将记录按行写入文件中, 另外可以实现从文本文件中按行读取记录,同时能够实现分页读取文本文件的内容
 * @author 李朋飞
 */
public class FileForJiluUtil {

    public static void createNewFile(String fileName) throws IOException {
        File myFilePath = new File(fileName);
        if (!myFilePath.exists()) {
            myFilePath.createNewFile();
        }
    }

    public static void appendJiluToFile(String fileName, String jilu) {
        try {
            createNewFile(fileName);
            // write string to file
            FileWriter writer = new FileWriter(fileName, true);
            BufferedWriter bw = new BufferedWriter(writer);
            bw.write(jilu);
//            bw.newLine();//如果是加了这个,会在文本文件里面显示了另外一行,不加的话,看到是连续的,也就是不是换行的,即使我的jilu字符串后面加了  \n
            bw.flush();
            bw.close();
            writer.close();

        } catch (IOException e) {
        }

    }
    private static int pageSize = 16;

    /**
     * anhang分页读取文件里面的内容
     *
     * @param pageNo
     * @param fileName
     */
    public static int readFileByPage(int pageNo, String fileName, JTextPane pane) {
        File file = new File(fileName);
        BufferedReader reader = null;
        try {
            System.out.println("以行为单位读取文件内容,一次读一整行:");
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            int line = 0;
            int index = 1;
            //一次读入一行,直到读入null为文件结束,由于我在写入文本文件的时候,在每个字符串后面都加了 \n,所以查看的时候,会在基数行显示内容,偶数行显示空字符串。所以加了一个偶数行的判断
            while ((tempString = reader.readLine()) != null) {
                //显示行号
                if (index % 2 != 0) {
                    line++;
                    if (line > (pageNo - 1) * pageSize && line <= pageNo * pageSize) {
                        System.out.println("line " + line + ": " + tempString);
                        Chat.insertIntoHistoryPane(pane, line+":    " + tempString);
                    }
                }

                index = index + 1;
                if (line > pageNo * pageSize) {
                    break;
                }
            }
            reader.close();
        } catch (IOException e) {
        }
        return pageNo;
    }

    /**
     * 以行为单位读取文件,常用于读面向行的格式化文件
     *
     * @param fileName 文件名
     */
    public static void readFileByLines(String fileName) {
        File file = new File(fileName);
        BufferedReader reader = null;
        try {
            System.out.println("以行为单位读取文件内容,一次读一整行:");
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            int line = 1;
            //一次读入一行,直到读入null为文件结束
            while ((tempString = reader.readLine()) != null) {
                //显示行号
                System.out.println("line " + line + ": " + tempString);
                line++;
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
    }
}




关于发送表情,我这里发送的不是表情文件,而是发送表情对应的一些特殊的编号,这个可能有点搓,思路也很垃圾,但还能用


      剩下最后一个问题,就是俩个聊天用户进行互相发送文件,由于对于java io编程以及java 网络编程,都不是很熟悉这个问题困扰了我一天,后来通过查阅资料,结合聊天室整个的流程,终于实现了用户互相传送文件,我这里的思路是当服务器端收到一个用户发来,我要发送文件的请求时,判断这个用户要发给谁,然后,使这俩个用户之间建立连接。发送文件的一方暂时作为服务器,接受方作为客户端。当文件传输成功之后,断开俩人的连接,具体的实现请参考附件源代码



今天终于有机会上传项目源文件了,另外里面包含了系统所需要的jar包。主要是一个mysql的jdbc驱动jar,和一个java mail的jar文件。为了节省空间,只上传了java mail的jar文件,另外mysql的驱动jar,网上太多。

项目运行主要是chatroom里面的server ,及client,先运行server。里面自己做了个找回密码的功能,找回密码是采用的发送邮件的方式

如果看不到附件,请去csdn下载,http://download.csdn.net/detail/a450065/4220644
分享到:
评论

相关推荐

    1.5Java聊天室的设计与实现socket.zip

    Java聊天室的设计与实现主要基于Socket编程,是Java开发领域中的一个典型实例,适用于学习和研究。这个毕业设计项目提供了完整的源代码,帮助学生或开发者深入理解网络通信和多线程编程。以下将详细讲解该项目涉及的...

    一部分网络编程笔记总结

    10. **实战项目**:实践中,可以开发简单的聊天室、文件传输、分布式任务调度等应用,通过网络编程实现不同节点间的信息交互。 以上就是Java网络编程的一些关键知识点,学习并掌握这些内容,能让你具备构建和维护...

    node.js + socket.io 实现点对点随机匹配聊天

    真心佩服那些可以经常发布笔记的人,其实我也想经常发来的,奈何技术不够加上懒,要向大神们多多学习了,前段时间有用bomb平台自带的socket写一个聊天室,其实基本就是改了改它的demo,这次想实现一个随机私聊,所以...

    Node基础学习笔记.rar

    WebSocket提供了一种全双工、低延迟的通信方式,常用于实时应用如聊天室、在线游戏等。Node.js中的ws或socket.io库可以帮助实现WebSocket服务器。学习WebSocket协议的工作原理、建立和断开连接、发送和接收消息,...

    NodejsNode-js笔记

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它让开发者可以用 JavaScript 来编写服务器端和网络应用。Node.js 使用了一个事件驱动、非阻塞 I/O 模型,使其轻量又高效,非常适合处理大量并发连接。在...

    中美 IT 培训 C# Asp.net 笔记2

    基于Web的咨询系统(基于Web的聊天室);3。论坛系统 通过实际项目深入理解和掌握相关的技术和知识点:Asp.Net、Ajax、 Ado.Net、Web Service等。 Windows 应用程序、设计模式和Oracle数据库编程(40课时) 系统地...

    中美 IT 培训 C# Asp.net 全套笔记1

    基于Web的咨询系统(基于Web的聊天室);3。论坛系统 通过实际项目深入理解和掌握相关的技术和知识点:Asp.Net、Ajax、 Ado.Net、Web Service等。 Windows 应用程序、设计模式和Oracle数据库编程(40课时) 系统地...

    中美 IT 培训 C# Asp.net 笔记3

    基于Web的咨询系统(基于Web的聊天室);3。论坛系统 通过实际项目深入理解和掌握相关的技术和知识点:Asp.Net、Ajax、 Ado.Net、Web Service等。 Windows 应用程序、设计模式和Oracle数据库编程(40课时) 系统地...

    值类型与引用类型理论内容.part01.rar

    基于Web的咨询系统(基于Web的聊天室);3。论坛系统 通过实际项目深入理解和掌握相关的技术和知识点:Asp.Net、Ajax、 Ado.Net、Web Service等。 Windows 应用程序、设计模式和Oracle数据库编程(40课时) ...

    值类型与引用类型理论内容.part05.rar

    基于Web的咨询系统(基于Web的聊天室);3。论坛系统 通过实际项目深入理解和掌握相关的技术和知识点:Asp.Net、Ajax、 Ado.Net、Web Service等。 Windows 应用程序、设计模式和Oracle数据库编程(40课时) ...

    Complete-Node.js-课程

    8. **实时通信**:WebSocket协议使得双向通信成为可能,Node.js可以利用socket.io库实现实时应用,如聊天室、在线游戏等。 9. **部署与运维**:最后,课程可能会讲解如何将Node.js应用部署到云平台(如Heroku、AWS...

    nodevember-2014-notes:来自田纳西州纳什维尔的 Nodevember 2014 会议的笔记

    笔记可能涵盖了WebSocket、Socket.IO和其他实时通信库的使用。 5. **性能优化**:如何通过工具如`profiler`来调试和优化Node.js应用程序,以及如何处理内存泄漏和CPU占用过高等问题。 6. **错误处理**:在Node.js...

    了不起的node.js读书笔记之例程分析

    通过Socket.IO,我们可以轻松实现聊天室和DJ功能,通过`socket.emit`发送事件,`socket.on`监听并处理事件,实现两端之间的实时通信。 7. **调试技巧**:在JavaScript开发中,了解如何有效地打印和调试对象非常有用...

    feelsokayegbot:斯莫尔感谢抽搐机器人

    Twitch是一个流行的在线游戏直播平台,而聊天机器人则常用于增强观众与主播之间的互动,提供各种功能如自动回复、管理聊天室、执行命令等。 在描述中提到,这个机器人已经集成了数据库,这意味着它有能力存储和检索...

Global site tag (gtag.js) - Google Analytics