`
Sunshyfangtian
  • 浏览: 243493 次
  • 性别: Icon_minigender_1
  • 来自: 惠州
社区版块
存档分类
最新评论

一个简单的UDP聊天室

阅读更多

以下资料是从别处直接Copy的,为了方便查找使用,放到“毕设手记”里了

一个简单的使用UDP协议实现的联天室,附件中有Eclipse3.4调试的project。

由两个包组成:server 和 client

 

server包里有如下两个类:

 

package server;

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class ServerFrame extends JFrame{

 private JTextArea allmsg;
 private JTextField currnum,totalnum,copyright,chatmsg;
 private JButton send;
 private JScrollPane js;
 int num1,num2,port;/*  -- num1:当前在线人数  num2:总上线人数  port:服务端口号 --*/
 
 private ServerSocket ss;
 
 ArrayList lists;//存放所有在线用户
 
 public ServerFrame()
 {
  super("聊天室服务器端");
  this.setSize(310,660);
  this.setLocation(200,50);
  
  lists = new ArrayList();
  
  num1 = num2 =0;
  port = 7777;
  
  currnum = new JTextField(" 当前在线人数: "+num1);
  currnum.setEnabled(false);
  
  totalnum = new JTextField(" 上线总人数: "+num2);
  totalnum.setEnabled(false);
  
  copyright = new JTextField("             -----  all copyright @ TOP-king  -----");
  copyright.setEnabled(false);  
  
  allmsg = new JTextArea();
  allmsg.append("                   --------------- 系统消息 --------------\n");
  allmsg.setEditable(false);
  allmsg.setLineWrap(true); //允许自动换行

  js = new JScrollPane(allmsg);//为JTextArea添加滚动条  

  
  chatmsg = new JTextField("在此输入系统信息");
  chatmsg.addActionListener(new ActionListener(){   

   public void actionPerformed(ActionEvent arg0) {
    String str = chatmsg.getText().trim();
    if(!"".equals(str))
      {sendmsg((new Date()).toLocaleString()+" -- 系统消息: "+str);chatmsg.setText("");}
    else
         JOptionPane.showMessageDialog(null, "消息不能为空","错误",JOptionPane.OK_OPTION);
    chatmsg.setText("");/*  -- 发送信息后,将输入栏中的信息清空 --  */
   }
  }); 
  
  send = new JButton("发送");
  send.addActionListener(new ActionListener(){   

   public void actionPerformed(ActionEvent arg0) {
    String str = chatmsg.getText().trim();
    if(!"".equals(str))
      {sendmsg((new Date()).toLocaleString()+" -- 系统消息: "+str);chatmsg.setText("");}
    else
         JOptionPane.showMessageDialog(null, "消息不能为空","错误",JOptionPane.OK_OPTION);
    chatmsg.setText("");/*  -- 发送信息后,将输入栏中的信息清空 --  */
   }
  });
  
  addcomponettocontainer();
  this.addWindowListener(new WindowAdapter(){
   public void windowClosing(WindowEvent we)
   {
    sendmsg("SYSTEM_CLOSED");/*  -- 向客户端发送服务器关闭信息 --  */
    destory();
   }
  });
  start(); /*  -- 启动连接服务 --  */
    
 }
 
 public void addcomponettocontainer()
 {
  Container c = this.getContentPane();
  c.setLayout(null);
  
  currnum.setBounds(20,15,130,20);
  totalnum.setBounds(155,15,125,20);
  js.setBounds(10,50,280,500);
  chatmsg.setBounds(10,560,180,30);
  send.setBounds(220,560,70,30);
  copyright.setBounds(10,600,280,20);
  
  c.add(currnum);
  c.add(totalnum);
  c.add(js);
  c.add(chatmsg);
  c.add(send);
  c.add(copyright);
  
  this.setVisible(true);
  this.setResizable(false);
 }
 
 
 /**  
  *  start()方法监听客户的连接
  *  并且保存客户端的相关信息EG:用户昵称、用户所使用的Socket
  *  用户连接到服务器成功之后,将其保存到用户列表中,并为该用户启动一个线程用于通信 */
 public void start()
 {
  boolean isStarted = false;/*  -- 用于标记服务器是否已经正常启动 --  */
  try {
   this.ss = new ServerSocket(port);
   isStarted = true;
   this.allmsg.append((new Date()).toLocaleString()+"    服务器启动 @ 端口: "+port+"\n");
   while(isStarted)
   {
    Socket client = this.ss.accept(); /*  -- 监听客户端的连接 --  */
    DataInputStream in = new DataInputStream(client.getInputStream());
    String name = in.readUTF();
    user u = new user();
    u.name = name;
    u.socket = client;
    lists.add(u); //将该用户加到列表中去
    num1++;
    num2++;
    currnum.setText(" 当前在线人数: "+num1);
    totalnum.setText(" 上线总人数: "+num2);
    this.allmsg.append((new Date()).toLocaleString()+" : "+u.name+" 登录 \n");
    new Thread(new ClientThread(u)).start();/*  -- 为该用户启动一个通信线程 --  */
   }
   
  } catch (IOException e) {
   System.out.println("服务器已经启动......");
   System.exit(0);
  }
 }

 /**
  * 通信线程主要功能包括:
  * 1.监听客户端输入的信息
  * 2.将接收到的信息转发给其他用户  */
 class ClientThread implements Runnable
 {
  user user = null;
  boolean isConnected = true;
  DataInputStream dis = null;
  DataOutputStream dos = null;
  
  public ClientThread(user u)
  {
      this.user = u; 
      try {
    this.dis = new DataInputStream(this.user.socket.getInputStream());
    this.dos = new DataOutputStream(this.user.socket.getOutputStream());
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  
  public void run()
  {
   readmsg();
  }
  
  /*  -- 读取客户的聊天信息 --  */
   public void readmsg()
   {
    while(isConnected)
    {
     try {         
      String msg = dis.readUTF();
      if("quit&logout".equals(msg))//当用户关闭客户端窗口时,发送quit字符串 表示用户已经退出
      {
       num1--;       
       try{
        this.dis.close();
        this.dos.close();
        this.user.socket.close();
        this.isConnected = false;
       }catch(IOException ioe)
       {
        ioe.printStackTrace();
       }finally{
        this.isConnected = false;
        if(dis!=null) this.dis.close();
        if(dos!=null) this.dos.close();
        if(this.user.socket!=null) this.user.socket.close();
       }
       lists.remove(this.user);//从列表中删除该用户
       currnum.setText(" 当前在线人数: "+num1);
       allmsg.append((new Date()).toLocaleString()+"  : "+this.user.name+"  退出\n");
      }
      else
      sendmsg(msg);
     } catch (IOException e) {
      e.printStackTrace();
     }
   }
   }    
     
 }
   
 /*  -- 将信息进行转发 --  */
 public void sendmsg(String msg)
    {
     user us = new user();
     DataOutputStream os = null;
     if(lists.size()>0)
     {
      for(int i=0;i<lists.size();i++)
         {
             us = (user)lists.get(i);
             try {   
              os = new DataOutputStream(us.socket.getOutputStream());
        os.writeUTF(msg);
       } catch (IOException e) {
        e.printStackTrace();
       }
         }
     } 
     else
      JOptionPane.showMessageDialog(null, "当前无用户在线。发送消息失败","失败",JOptionPane.OK_OPTION);
    } 
 
    public void destory()
    {
     try {
   this.ss.close();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  this.dispose();
    }
    
 public static void main(String[] args)
 {
  new ServerFrame();
 }

}

 

 

 

package server;

import java.net.*;

public class user {

  String name;
  Socket socket;
}

 

 

 

client包里有如下两个类:

 

1.

 

package client;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

public class LoginFrame extends JFrame{
 private JTextField name;
 private JTextField ip;
 private JButton ok,cancle;
  
 public Socket socket;
 
 public LoginFrame()
 {
  super("登录框");
  this.setSize(400,80);
  this.setLocation(100,100);  
   
  name = new JTextField("昵称");   
  ip = new JTextField("127.0.0.1");
  ok = new JButton("登录");
  cancle = new JButton("取消");
  ok.addActionListener(new listenEvent());
  cancle.addActionListener(new listenEvent());
  
  addcomponettocontainer();
  this.setDefaultCloseOperation(EXIT_ON_CLOSE);
  
 }

 public void addcomponettocontainer()
 {
  Container c = this.getContentPane();
  c.setLayout(null);
  
  name.setBounds(10,10,100,30);
  ip.setBounds(120,10,100,30);
  ok.setBounds(230,10,70,30);
  cancle.setBounds(310,10,70,30);
  
  c.add(name);
  c.add(ip);
  c.add(ok);
  c.add(cancle);
  
  this.setVisible(true);
  this.setResizable(false);
 }
 
 public class listenEvent implements ActionListener
 {

  public void actionPerformed(ActionEvent event) {
   // TODO Auto-generated method stub
   if(event.getSource()==ok)
   {
    String n = name.getText().trim();
    String i = ip.getText().trim();
    if("".equals(n)||"".equals(i))
    {
     JOptionPane.showMessageDialog(null,"昵称、IP不能够为空!","错误",JOptionPane.OK_OPTION);
    }
    else{login(n,i);}
   }
   if(event.getSource()==cancle)
   {
    name.setText("");
    ip.setText("");
   }
  }
  
 }
 
 public void login(String name,String ip)
 {
  
   try {
    socket = new Socket(ip,7777);
    DataOutputStream out = new DataOutputStream(socket.getOutputStream());
    out.writeUTF(name);
    out.flush();//强制输出缓存中的内容
    //out.close();
    new ClientFrame(name,socket);
    destroywindow();
   } catch (UnknownHostException e) {
    JOptionPane.showMessageDialog(null,"找不到主机地址(IP错误/网络故障)!","错误",JOptionPane.OK_OPTION);
    
   } catch (IOException e) {
    
   }         
 }
 
 public void destroywindow()
 {  
  this.dispose();
 }
 
 public static void main(String[] args)
 {
  new LoginFrame();
 }
}

 

 

package client;

import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Date;

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

public class ClientFrame extends JFrame{
 private JTextArea allmsg;
 private JTextField welcome,copyright,chatmsg;
 private JButton send;
 private JScrollPane js;
    private boolean isConnected = true;
 
 public DataOutputStream out;
 public DataInputStream in;
 
 public Socket s = null; 
 
 String nic;  /*  -- 保存用户昵称 --*/
 
 
 /**
  * 初始化客户端资源
  * 1.获取从LoginFrame传递过来的参数
  * 2.初始化界面元素
  * 3.初始化通信所需要的资源 EG:输入/输出流(DataInputStream/DataOutputStream)
  * */ 
 public ClientFrame(String name,Socket socket)
 {  
  this.setSize(310,660);
  this.setLocation(290,50);  
        this.setTitle("聊天室客户端<"+name+">");/*  -- 指定窗口的标题 --*/
        
  this.s = socket;/*  -- 接收从LoginFrame中传递过来的Socket --*/  
  
  this.nic = name+" 说: ";
  
  
  welcome = new JTextField(" < "+name+" >欢迎您来到聊天室 ",100);
  welcome.setBackground(Color.blue);  
  welcome.setEnabled(false);
  
  copyright = new JTextField("             -----  all copyright @ TOP-king  -----");
  copyright.setEnabled(false);
  
  allmsg = new JTextArea();
  allmsg.setEditable(false);
  allmsg.append("                  系统消息: 欢迎登录在线聊天室 \n");
  
  js = new JScrollPane(allmsg);//为JTextArea添加滚动条  
  
  chatmsg = new JTextField("在此输入聊天信息");
  chatmsg.addActionListener(new listen());
  
  send = new JButton("发送");
  send.addActionListener(new listen());/*  -- 添加事件监听器 --*/
  
  try {    
   out = new DataOutputStream(s.getOutputStream());   
   in = new DataInputStream(s.getInputStream());   
  } catch (IOException e) {JOptionPane.showMessageDialog(null, "系统异常","错误",JOptionPane.OK_CANCEL_OPTION);}
  
  addcomponettocontainer();

  /*  -- 当用户关闭窗口时进行相关的处理 eg:Socket Data(Input/Output)Stream 的关闭--*/
  this.addWindowListener(new WindowAdapter(){
   public void windowClosing(WindowEvent we)
   {
    sendmsg("quit&logout");/*  -- 向服务器端发送关闭信息 --*/
    isConnected = false;
    destory();/*  -- 销毁窗口资源 --*/
   }
  });
  
  new Thread(new linread()).start();/*  -- 启动读取信息线程 --*/
  
 }
 
 public void addcomponettocontainer()
 {
  Container c = this.getContentPane();
  c.setLayout(null);
  
  welcome.setBounds(75,10,150,20);  
  js.setBounds(10,50,280,500);
  chatmsg.setBounds(10,560,180,30);
  send.setBounds(220,560,70,30);
  copyright.setBounds(10,600,280,20);
  
  c.add(welcome);
  c.add(js);
  c.add(chatmsg);
  c.add(send);
  c.add(copyright); 
    
  this.setVisible(true);
  this.setResizable(false);
 }
 
 class listen implements ActionListener
 {

  public void actionPerformed(ActionEvent e) {
   // TODO Auto-generated method stub
   if(e.getSource()==send||e.getSource()==chatmsg)
   {
      String msg = chatmsg.getText().trim();
      if("".equals(msg))
      {
       JOptionPane.showMessageDialog(null,"发送信息不能为空!","错误",JOptionPane.OK_OPTION);
      }
      else
      {sendmsg((new Date()).toLocaleString()+"\n"+nic+msg+"\n");chatmsg.setText("");}
   }
  } 
 }
 
 /*  -- 向服务器端发送信息 --*/
  public void sendmsg(String m)
  {
   if(isConnected)//如果socket的输出流没关闭
   {
    try {
     out.writeUTF(m);
    } catch (IOException e) {
     JOptionPane.showMessageDialog(null,"发送信息失败!(系统异常)","错误",JOptionPane.OK_OPTION);
    }
   }
   else
   {
    JOptionPane.showMessageDialog(null,"发送信息失败!(服务器关闭/网络故障)","错误",JOptionPane.OK_OPTION);
   }
  }

  /*  -- 读取信息线程 --*/
 class linread implements Runnable
 {  
  public void run()
  {
   read();
  }
  
  public void read()
  {
    while(isConnected)
    {
     try {
      String msg = in.readUTF();
      if("SYSTEM_CLOSED".equals(msg))
      {
       JOptionPane.showMessageDialog(null,"读取消息失败(服务器关闭/网络故障)!","错误",JOptionPane.OK_OPTION);
       isConnected = false;
      }
      else
        allmsg.append(msg+"\n");      
      } catch (IOException e) {     
      }                  
    }//end while 
    JOptionPane.showMessageDialog(null,"读取消息失败(服务器关闭/网络故障)!","错误",JOptionPane.OK_OPTION);
   }//end read()
 }
 
  public void destory()
  {
   try {
    this.out.close();
    this.in.close();
    this.s.close();
   } catch (IOException e) {   
   }
   this.dispose();
  }
}

 

 

 

二、运行情况

 



 



 



 

  • 大小: 59.7 KB
  • 大小: 75.3 KB
  • 大小: 74.1 KB
分享到:
评论
1 楼 zhaoshaofang 2011-07-30  
很好···我开始学习··有用·

相关推荐

    简单UDP聊天室 java版

    【标签】:“UDP聊天室”进一步强调了这个项目的核心在于实现一个基于UDP的多人交流平台。 从【压缩包子文件的文件名称列表】:“UDPChatRoom水机吧”来看,这可能是项目代码的主目录或者是包含源代码的文件夹,但...

    UDP简易聊天室

    在UDP聊天室中,当一个用户成功连接到服务器并登录后,服务器会广播一条消息,通知所有在线用户新用户已上线。这涉及到UDP的无连接特性和广播机制。UDP不需要像TCP那样建立连接,而是直接发送数据报文,因此可以...

    UDP聊天室客户端

    【UDP聊天室客户端】是一个基于C++编程语言实现的网络通信工具,主要利用了用户数据报协议(User Datagram Protocol,UDP)进行数据传输。UDP是一种无连接、不可靠的传输协议,它不保证数据包的顺序、不进行重传,...

    C#UDP聊天室

    【C# UDP聊天室】是一个基于C#编程语言实现的简单网络通信应用,它利用了用户数据报协议(UDP)进行数据传输。UDP是一种无连接的、不可靠的传输协议,相比TCP,它更注重速度和低延迟,适用于实时通信如语音聊天、...

    udp实现聊天室项目

    综上所述,这个项目展示了如何利用UDP协议、SQLite3数据库和链表数据结构来创建一个简单的聊天室应用。开发者需要具备UDP协议理解、数据库操作和链表数据结构的使用经验,同时熟悉C语言编程,才能成功实现这样的项目...

    udp聊天室源码

    UDP聊天室源码是一个基于用户数据报协议(UDP)实现的多用户聊天应用程序。UDP是一种无连接的、不可靠的传输层协议,它相对于TCP(传输控制协议)来说,具有更低的延迟和更高的效率,适合实时通信或者对数据丢失不太...

    基于UDP协议的聊天室设计

    【基于UDP协议的聊天室设计】是一个典型的网络编程项目,主要涵盖了UDP(用户数据报协议)的基础知识,以及如何利用这种协议实现一个简单的聊天室功能。UDP是传输层的一种无连接协议,它不保证数据包的顺序、完整性...

    外文文献UDP聊天室程序

    - **ACK机制的引入**:为了提高通信的可靠性,在UDP聊天室中加入了消息确认机制,即每个发送的消息都会收到一个确认(ACK),确保消息的有效送达。 - **多播通信**:利用UDP的多播功能,可以实现在多个客户端间高效...

    UDP实现简单聊天室功能

    创建一个简单的UDP聊天室,我们需要以下几个主要步骤: 1. **服务器端**: - 创建一个UDP套接字,使用`socket()`函数。 - 绑定IP地址和端口,使用`bind()`函数,通常选择INADDR_ANY来监听所有网络接口。 - 开始...

    java之UDP聊天室

    Java之UDP聊天室是一个实现多对多通信的项目,它基于用户数据报协议(User Datagram Protocol,UDP)来构建。UDP是一种无连接的、不可靠的传输层协议,相较于TCP,它具有更低的延迟和更高的效率,适合实时通信或者对...

    vb6 udp 聊天室

    在VB6(Visual Basic 6)环境中开发一个UDP聊天室是一项涉及网络编程和多线程技术的任务。UDP(User Datagram Protocol)是一种无连接的、不可靠的传输协议,常用于实时数据交换,如在线游戏和视频流等。下面将详细...

    c语言实现的udp聊天室

    本项目“C语言实现的UDP聊天室”是一个基础的网络通信示例,它利用了用户数据报协议(UDP)进行数据传输,为用户提供一个简单的多人聊天环境。UDP是一种无连接的、不可靠的传输协议,相对于TCP而言,它的特点是速度...

    C#实现UDP简单聊天室功能(winform版)

    开发工具使用的是VS2017,基于UDP协议实现的一个简单聊天室功能,包括客户端和服务器端,首先运行服务器端,接着调试-&gt;启动新实例开启多个客户端,每开启一个客户端,服务器端会显示XXX连接等提示。客户端发送消息给...

    QT UDP聊天室软件

    总的来说,QT UDP聊天室软件是一个很好的学习案例,它结合了QT的图形界面设计和网络通信能力,展示了如何在实际项目中运用UDP协议。通过理解并实践这个项目,开发者可以提升在网络编程和QT应用开发方面的技能。

    基于UDP的简单局域网聊天室框架

    【基于UDP的简单局域网聊天室框架】是一种利用UDP(User Datagram Protocol)协议实现的简易聊天室系统,适用于初学者学习网络编程。这个框架主要实现了基础的群聊功能,包括用户上线、下线以及成员列表的变化显示。...

    TCP+UDP聊天室

    在IT行业中,网络通信是至关...这个“TCP+UDP聊天室”的项目不仅涉及到网络通信的基本原理,还涵盖了系统设计、协议设计、错误处理、并发编程等多个IT领域的实践知识,是学习和提升网络编程技能的一个良好实践案例。

    聊天室 linux c udp

    综上,这个“聊天室 Linux C UDP”项目是一个实践性的教学案例,旨在教授网络编程的基本概念,特别是如何利用UDP协议在Linux环境中构建一个实时聊天应用。通过对源代码的学习和实际操作,开发者可以深入理解网络编程...

    UDP聊天室.zip

    使用 Qt 基于 UDP 协议构建网络聊天室实例,包含 UdpServerDemo 和 UdpClientDemo 两部分程序,由于 UDP 方式不会建立连接,所以在服务端采用QList容器管理客户端状态。

    udp聊天室16031125,udp聊天室 java,Python

    "udp聊天室16031125" 是一个特定的项目名称,表明这是一个基于UDP协议的网络聊天室实现,时间戳“16031125”可能指的是项目的创建或更新日期。"udp聊天室 java,Python" 指出该聊天室的实现涉及两种编程语言:Java和...

Global site tag (gtag.js) - Google Analytics