JavaSE项目之聊天室

引子:

当前,互联网 体系结构的参考模型主要有两种,一种是OSI参考模型,另一种是TCP/IP参考模型。

一、OSI参考模型,即开放式通信系统互联参考模型(OSI/RM,Open Systems Interconnection Reference Model),是国际标准化组织(ISO)提出的一个试图使各种计算机在世界范围内互连为网络的标准框架,简称OSI。

OSI参考模型将实现网络互连的通信协议分为7层,自上而下分别是:

第7层应用层:OSI中的最高层,为用户提供各项互联网应用,如公司老板通过浏览器上网、发送电子邮件等。 常见的协议有:HTTP,HTTPS,FTP,TELNET,SSH,SMTP,POP3等。

第6层表示层:相当公司中替老板写信的助理。

第5层会话层:相当于公司中收寄信、写信封与拆信封的秘书。

第4层传输层:提供终端到终端的可靠连接,相当于公司中跑邮局的送信职员。

第3层网络层: 确保信件通过一系列路由到达目的地。

第2层数据链路层: 决定访问网络介质的方式,并处理流控制。

第1层物理层:处于OSI参考模型的最底层,物理层的主要功能是利用物理传输介质为数据链路层提供物理连接,以便透明地传输比特流;该层的常用设备有网卡、集线器、中继器、调制解调器、网线、双绞线、同轴电缆等各种物理设备。

数据发送时,从第七层传到第一层,接收数据则相反。

上三层总称为“应用层”,用来控制软件方面;下四层总称为“数据流层”,用来管理硬件。除了物理层之外,其他层都是用软件实现的。

二、TCP/IP参考模型。

┌────------────┐┌─┬─┬─-┬─┬─-┬─┬─-┬─┬─-┬─┬─-┐

│        ││D│F│W│F│H│G│T│I│S│U│ │

│        ││N│I│H│T│T│O│E│R│M│S│其│

│第四层,应用层 ││S│N│O│P│T│P│L│C│T│E│ │

│        ││ │G│I│ │P│H│N│ │P│N│ │

│        ││ │E│S│ │ │E│E│ │ │E│它│

│        ││ │R│ │ │ │R│T│ │ │T│ │

└───────------─┘└─┴─┴─-┴─┴─-┴─┴─-┴─┴─-┴─┴-─┘

  ┌───────-----─┐┌─────────-------┬──--------─────────┐

  │第三层,传输层 ││   TCP   │    UDP    │

  └───────-----─┘└────────-------─┴──────────--------─┘

  ┌───────-----─┐┌───----──┬───---─┬────────-------──┐

  │        ││     │ICMP│          │

  │第二层,网间层 ││     └──---──┘          │

  │        ││       IP            │

  └────────-----┘└────────────────────-------------─-┘

  ┌────────-----┐┌─────────-------┬──────--------─────┐

  │第一层,网络接口││ARP/RARP │    其它     │

  └────────------┘└─────────------┴─────--------──────┘

我们在对上述两种参考模型有些了解后,接下来主要看TCP和UDP。我们先来看二者的区别:

1.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接;

2.TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付;

3.TCP面向字节流,实际上是TCP把数据看成是一连串无结构的字节流;UDP是面向报文的,它没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(如IP电话,实时视频会议等)

4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信;

5.TCP首部开销20字节;UDP的首部开销小,只有8个字节;

6.TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。

在Java中,对遵守TCP协议的类有ServerSocket和Socket,遵守UDP协议的类有DatagramSocket。我这里提供的聊天室项目,是基于TCP协议的。

该项目分为4个包,分别是utils(提供工具),ui(提供窗体界面),server(服务器子线程),client(客户端子线程)。

utils包下有两个类,分别是HostInfo和Release。HostInfo.java代码如下:

import java.net.InetAddress;

import java.net.UnknownHostException;

public abstract class HostInfo {

public static  String IP=getIP();

public static final int PORT=10086;

public static final int NUM=50;

public static final String NEW_LINE="\r\n";

private static String getIP(){

try {

return InetAddress.getLocalHost().getHostAddress();

} catch (UnknownHostException e) {

e.printStackTrace();

return null;

}

}

}

Release.java的代码如下:

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

public abstract class Release {

public static void release(Socket socket,BufferedWriter bw){

release(null,socket,null,bw);

}

public static void release(Socket socket,BufferedReader br){

release(null,socket,br,null);

}

public static void release(Socket socket){

release(null,socket,null,null);

}

public static void release(ServerSocket server){

release(server,null,null,null);

}

public static void release(ServerSocket server,Socket socket,BufferedReader br,BufferedWriter bw){

if(server!=null){

try {

server.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(socket!=null){

try {

socket.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(br!=null){

try {

br.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(bw!=null){

try {

bw.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

ui包下有两个类,分别是UIserver和UIclient。UIserver.java的代码如下:

import java.awt.Dimension;

import java.awt.FlowLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.JTextField;

import 聊天室.server.Server;

import 聊天室.utils.HostInfo;

public class UIserver extends JFrame {

private JPanel jp=new JPanel();

private JLabel jl_ipTips=new JLabel("服务器ip:");

public static JTextField jtf_ip=new JTextField(HostInfo.IP);

private JLabel jl_portTips=new JLabel("服务器端口:");

public static JTextField jtf_port=new JTextField(HostInfo.PORT+"");

public static JButton bt_open=new JButton("启动服务器");

public static JTextArea jta_log=new JTextArea();

private JScrollPane jsp_log=new JScrollPane(jta_log);

public UIserver(){

jp.setLayout(new FlowLayout());

jp.add(jl_ipTips);

jp.add(jtf_ip);

jp.add(jl_portTips);

jp.add(jtf_port);

jp.add(bt_open);

jp.add(jsp_log);

jl_ipTips.setPreferredSize(new Dimension(100, 50));

jtf_ip.setPreferredSize(new Dimension(150, 50));

jl_portTips.setPreferredSize(new Dimension(100, 50));

jtf_port.setPreferredSize(new Dimension(150, 50));

bt_open.setPreferredSize(new Dimension(260, 50));

jsp_log.setPreferredSize(new Dimension(260, 192));

jta_log.setLineWrap(true);

jta_log.setEditable(false);

bt_open.addActionListener(new ActionListener(){

@Override

public void actionPerformed(ActionEvent arg0) {

new Server().start();

}

});

add(jp);

setTitle("聊天应用控制服务器");

setBounds(100, 50, 300, 400);

setResizable(false);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setVisible(true);

}

public static void main(String[] args) {

new UIserver();

}

}

UIclient.java的代码如下:

import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.FocusAdapter;

import java.awt.event.FocusEvent;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.JTextField;

import 聊天室.client.Client;

public class UIclient extends JFrame {

private JPanel jp_chat=new JPanel();

public static JTextArea jta_chat=new JTextArea();

private JScrollPane jsp_chat=new JScrollPane(jta_chat);

private JPanel jp_send=new JPanel();

public static  JTextField jtf_desip=new JTextField("请输入对方Ip");

public static  JTextArea jta_message=new JTextArea();

private JScrollPane jsp_message=new JScrollPane(jta_message);

private JButton bt_send=new JButton("发送");

private Client client;

public UIclient(){

jp_chat.add(jsp_chat);

jta_chat.setLineWrap(true);

jta_chat.setEditable(false);

jsp_chat.setPreferredSize(new Dimension(550, 400));

jp_send.add(jtf_desip);

jp_send.add(jsp_message);

jta_message.setLineWrap(true);

jp_send.add(bt_send);

jtf_desip.setPreferredSize(new Dimension(100, 50)); 

jsp_message.setPreferredSize(new Dimension(250, 50));

bt_send.setPreferredSize(new Dimension(100, 50));

jtf_desip.addFocusListener(new FocusAdapter(){

@Override

public void focusGained(FocusEvent e) {

jtf_desip.setText("");

}

});

jta_message.addFocusListener(new FocusAdapter(){

@Override

public void focusGained(FocusEvent e) {

jta_message.setText("");

}

});

bt_send.addActionListener(new ActionListener(){

@Override

public void actionPerformed(ActionEvent arg0) {

client.send();

}

});

add(jp_chat, BorderLayout.CENTER);

add(jp_send, BorderLayout.SOUTH);

setTitle("群聊窗口");

setBounds(300, 100, 600, 500);

setResizable(false);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setVisible(true);

client=new Client();

client.start();

}

public static void main(String[] args) {

new UIclient();

}

}

server包下有两个类,分别是Server和Transport。Server.java的代码如下:

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.List;

import 聊天室.ui.UIserver;

import 聊天室.utils.HostInfo;

import 聊天室.utils.Release;

public class Server extends Thread {

private ServerSocket server;

public static List<Transport> clients=new ArrayList<>();

@Override

public void run() {

try {

server=new ServerSocket(Integer.parseInt(UIserver.jtf_port.getText().trim()));

} catch (IOException e) {

Release.release(server);

throw new RuntimeException("服务器端口被占!");

}

UIserver.bt_open.setText("已启动服务器");

UIserver.bt_open.setEnabled(false);

UIserver.jta_log.append("服务器成功启动!"+HostInfo.NEW_LINE);

new Accept().start();

}

class Accept extends Thread{

private Socket socket;

@Override

public void run() {

int num=0;

while(num<HostInfo.NUM){

try {

socket=server.accept();

} catch (IOException e) {

Release.release(socket);

throw new RuntimeException("客户端连接失败!");

}

num++;

String str="第 "+num+" 个客户端连接成功!==>"+socket.getInetAddress().getHostAddress()+" :"+socket.getPort()+HostInfo.NEW_LINE;

UIserver.jta_log.append(str);

clients.add(new Transport(socket));

}

UIserver.jta_log.append("超出服务器负荷!");

Release.release(server);

}

}

}

Transport.java的代码如下:

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.Socket;

import 聊天室.utils.Release;

public class Transport extends Thread {

private Socket socket;

private String ip;

public Transport(Socket socket){

this.socket=socket;

this.ip=socket.getInetAddress().getHostAddress();

this.start();

}

@Override

public void run() {

BufferedReader br=null;

BufferedWriter ownbw=null;

try {

br=new BufferedReader(new InputStreamReader(socket.getInputStream()));

ownbw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

} catch (IOException e) {

Server.clients.remove(this);

Release.release(socket);

throw new RuntimeException("获取流失败!");

}

String str=null;

try {

while((str=br.readLine())!=null){

String[] split = str.split(":", 2);

if(split.length<=1){

ownbw.write("数据格式错误!");

ownbw.newLine();

ownbw.flush();

}

String desip=split[0];

String content=split[1];

BufferedWriter desbw=null;

boolean isOnLine=false;

for(Transport des:Server.clients){

if(desip.equals(des.ip)){

isOnLine=true;

desbw=new BufferedWriter(new OutputStreamWriter(des.socket.getOutputStream()));

desbw.write(str);

desbw.newLine();

desbw.flush();

}

}

if(!isOnLine){

ownbw.write("对方不在线!");

ownbw.newLine();

ownbw.flush();

}

}

} catch (IOException e) {

Server.clients.remove(this);

Release.release(socket);

throw new RuntimeException("获取流失败!");

}

}

}

client包下有一个类Client.java,该类的代码如下:

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.Socket;

import 聊天室.ui.UIclient;

import 聊天室.ui.UIserver;

import 聊天室.utils.HostInfo;

import 聊天室.utils.Release;

public class Client extends Thread {

private Socket socket;

@Override

public void run() {

try {

socket=new Socket(UIserver.jtf_ip.getText().toLowerCase(), Integer.parseInt(UIserver.jtf_port.getText().trim()));

}  catch (IOException e) {

Release.release(socket);

throw new RuntimeException("客户端创建失败!");

}

BufferedReader br=null;

try {

br=new BufferedReader(new InputStreamReader(socket.getInputStream()));

} catch (IOException e) {

Release.release(socket);

throw new RuntimeException("获取流失败!");

}

String str=null;

try {

while((str=br.readLine())!=null){

UIclient.jta_chat.append(str+HostInfo.NEW_LINE);

}

} catch (IOException e) {

Release.release(socket);

throw new RuntimeException("获取流失败!");

}

}

public void send(){

new Send().start();

}

class Send extends Thread{

@Override

public void run() {

BufferedWriter bw=null;

try {

bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

} catch (IOException e) {

Release.release(socket,bw);

throw new RuntimeException("获取流失败!");

}

String str=UIclient.jtf_desip.getText().trim()+":"+UIclient.jta_message.getText().trim();

try {

bw.write(str);

bw.newLine();

bw.flush();

} catch (IOException e) {

Release.release(socket,bw);

throw new RuntimeException("获取流失败!");

}

}

}

}

原文地址:https://www.cnblogs.com/lizhangyong/p/8137686.html

时间: 2024-08-03 14:46:47

JavaSE项目之聊天室的相关文章

小项目:聊天室 (jQuery,PHP,MySQL)

这几天写了一个小项目,初衷是自己写一个有前端,有后端的东西练练手,所以,实际意义并不大,只是拿来试试手而已. 我对这个聊天室的构想是这样的:先建两个数据库,一个保存用户名和密码,另一个保存用户名和发送的信息,并记录发送的时间,网页上也想了很多骚操作,但是最后也就简简单单的卡了几张图在两边,简洁,勉强算是美观可看.用户登陆之后,网页就开始下载数据库的信息,并把用户发送的信息一个个垒成盒子向腾讯一样发出来.额...想来真是简单,我竟然写了一星期左右. 时间其实大部分耗费在处理后台发送过来的数据上面,

javase基础学完可以做什么,javase实现局域网聊天室

包含内容:基础语法,面向对象,多线程,IO流,GUI编程,网络编程(udp) 实现功能:局域网群聊,局域网群发文件(还不太完善,只能传输小体积的文本文件) 由于本人也是刚开始学java,而且掌握的不太好,所以代码可能有些臃肿.请谅解 登录界面 群聊界面 代码写一个java文件里了,不太方便阅读. 1 package test; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import java.io.*; 6 import java.n

对我们的团队项目:聊天室菜园的看法

我们通过了第一周的一个冲刺阶段,对我们的聊天软件菜园做出了一个初步的软件,现有的只实现了一个在局域网的客户端和服务器端的连接以及显示各个用户的聊天记录,具体的更大的需求我们还没有做一个好的分析也还没有做.我现在的分析:我们缺少一个像QQ或者微信那样几乎所有聊天软件所共有的一个聊天好友列表,以及好友的添加分组功能,因此需要做一个好友列表的界面并实现好友的添加删除:我觉得我们的聊天功能还太少,现在只能用文字交流还有几个特定的状态的,不足以满足现在用户的需求,我们需要做图片以及表情包的快捷发送,如果还

自写聊天室_LinuxC实现(4)——项目文档

西邮Linux兴趣小组  暑期项目 项目名称:    happychat        项目作者:      楚东方     1. 引言 1.1 项目综述 对项目进行简要介绍,并说明编写此项目的目的. 该项目为聊天室,主要为了实现聊天,文件传输,方便linux环境下的,交流与聊天. 实现功能: 1.好友管理: (1)添加好友 (2)删除好友 2.群管理 (1)创建群 (2)加群 (3)退群 (4)解散群 3.文件传送 实现了上传和下载的断点续传 4.聊天界面分屏 利用光标的移动对输入和屏幕聊天记

JavaSE项目--------聊天室

JAVASE聊天室 客户端:import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.net.SocketException;import java.util.Scanner; import Clinet.untils.InputUtil;import Configs.Configs; public class Clien

Python项目实战教程:web实时聊天室项目

新课强力来袭:基于Node.js的web实时聊天室项目! 麦子学院新课以马踏飞燕般的速度生粗来啦(*^__^*) .小伙伴们你萌确定不来一发吗? 啦啦啦--上图镇楼↓↓↓ 那些神奇的传送门→_→ 本课程:http://www.maiziedu.com/course/others/597-8698/ 李大大主页:http://www.maiziedu.com/group/common/course/59404/ 这里是正儿八经的课程介绍(快看快看o( ̄ヘ ̄o#)): 网站实时通讯一体化解决方案,采

多功能聊天室-项目规划实现图

网络编程项目规划 最近在练习一个项目吧,大概给6天的时间来完成它,其中涉及到了数据库的知识,网络编程,linux C等等,大考验的时刻到了!我知道PM们的项目规划图绝对比我的高大上,但是咱也不能没有自信对不?因此,我开始先分析我的项目它有什么功能需求,需求分析完成了,OK,那么项目应该大体上,又是靠什么来实现的呢?这是一个最值得深究的问题!又有人说,那不是得用代码来实现吗?等等,那样你得写到什么时候?因而我们绝对不是先用代码去实现功能,而是把功能提取出来,了解他实现的过程!重要的是什么?嘿嘿,让

springmvc与+hibernate制作的一个聊天室(开源项目)

前段时间有了点空暇时间,然后某一门课要求搞一个聊天室,所以使用springmvc和hibernate搞了一个还不错的聊天室项目.页面比較精美. 多的不说了.先上图,个人觉得是精品: 登录: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjczNDQ0MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > 注冊: watermark/2

基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。

基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室.