- package tcpip;
- import javax.swing.*;
- import java.awt.*;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.KeyAdapter;
- import java.awt.event.KeyEvent;
- import java.net.*;
- import java.util.Calendar;
- import java.io.*;
- /**
- * 此类通过UDP实现聊天功能。<br/>
- * 学校局域网内只能ping通网关和本机地址,对于局域网内其他主机ping不通。<br/>
- * 本次实验时用一根网线直接连通两台笔记本电脑,可以互相ping通。<br/>
- * 两台主机地址分别为:169.254.105.44和169.254.116.48<br/>
- * <br/>
- * 注:菜单栏中除了退出,其他菜单并没有实质性的作用。<br/>
- * */
- public class Chat extends JFrame{
- private static final long serialVersionUID = 1L;
- //定义的组件
- Container c = this.getContentPane();
- TimeLabel timeLab;
- Recv recvMsg;
- JTextField sendMsg;
- JButton sendBut;
- JDialog helpDia;
- JLabel helpLab;
- DatagramSocket ds ;
- //菜单栏
- JMenuBar menuBar ;
- JMenu operate ;
- JMenuItem option ;
- JMenu hehe ;
- JMenu xixi;
- JMenuItem heihei;
- JMenu help;
- JMenu info;
- JMenuItem infomation;
- JMenuItem about;
- /**
- * 此构造方法调用init()函数<br/>
- * */
- public Chat(){
- init();
- }
- /**
- * 用于初始化各组件<br/>
- * */
- public void init(){
- this.setLayout(new BorderLayout());
- this.setBounds(300, 100, 600, 500);
- this.setTitle("LAN Chat");
- try {
- ds = new DatagramSocket();
- } catch (SocketException e) {
- e.printStackTrace();
- }
- //初始化菜单栏
- menuBar = new JMenuBar();
- operate = new JMenu("operate");
- option = new JMenuItem("quit");
- hehe = new JMenu("hehe");
- xixi = new JMenu("xixi");
- heihei = new JMenuItem("heihei");
- xixi.add(heihei);
- hehe.add(xixi);
- operate.add(hehe);
- operate.add(option);
- help = new JMenu("help");
- info = new JMenu("info");
- infomation = new JMenuItem("infomation");
- info.add(infomation);
- about = new JMenuItem("about");
- help.add(info);
- help.add(about);
- menuBar.add(operate);
- menuBar.add(help);
- this.setJMenuBar(menuBar);
- //初始化显示时间Lable
- timeLab = new TimeLabel();
- Thread timeThread = new Thread(timeLab);
- timeThread.start();
- timeLab.setHorizontalAlignment(SwingConstants.RIGHT);
- c.add(timeLab,"North");
- //用于接收数据的文本框并设置滚动条
- //文本框设置滚动条应将文本框作为参数传给滚动条
- //最后将滚动条组件添加到容器中!!而不是将文本框组件添加到容器中
- recvMsg = new Recv();
- JScrollPane jsp = new JScrollPane(recvMsg);
- c.add(jsp);
- recvMsg.setEditable(false);
- Thread recvThread = new Thread(recvMsg);
- recvThread.start();
- //c.add(recvMsg,"Center");
- //添加一个面板,用于封装输入框和按钮
- JPanel panel = new JPanel();
- panel.setLayout(new FlowLayout());
- c.add(panel,"South");
- //输入框
- sendMsg = new JTextField(45);
- panel.add(sendMsg);
- //发送按钮
- sendBut = new JButton("send");
- panel.add(sendBut);
- //事件s
- events();
- this.setVisible(true);
- this.setResizable(false);
- //初始化菜单栏需要用到的对话框和标签
- helpLab = new JLabel();
- helpLab.setHorizontalAlignment(SwingConstants.CENTER);
- helpDia = new JDialog(this,true);
- helpDia.setBounds(380, 250, 400, 110);
- helpDia.add(helpLab);
- }
- /**
- * 所有组件的事件都放在此方法中<br/>
- * 包括:send按钮和回车发送信息;菜单的退出功能和菜单的信息显示。<br/>
- * */
- public void events(){
- //发送按钮事件
- sendBut.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- try {
- sendEvent();
- } catch (Exception e1) {
- e1.printStackTrace();
- }
- }
- });
- //发送框事件
- sendMsg.addKeyListener(new KeyAdapter() {
- public void keyPressed(KeyEvent e){
- if(e.getKeyCode()==KeyEvent.VK_ENTER){
- try {
- sendEvent();
- } catch (Exception e1) {
- e1.printStackTrace();
- }
- }
- }
- });
- //菜单栏事件--退出
- option.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- System.exit(0);
- }
- });
- //菜单栏事件--信息
- infomation.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- helpDia.setTitle("Infomation");
- helpLab.setText("this is the infomation you may want...");
- helpDia.setVisible(true);
- }
- });
- //菜单栏事件--关于
- about.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- helpDia.setTitle("about");
- helpLab.setText("<html>@author:wayne<br>" +
- "@time:12/12/9<br>" +
- "@blabla...</html>");
- helpDia.setVisible(true);
- }
- });
- }
- /**
- * 为了方便讲发送功能封装成一个函数<br/>
- * 回车或者发送按钮都会触发该事件<br/>
- * */
- public void sendEvent() throws Exception{
- DatagramPacket dp = null;
- byte []buf = sendMsg.getText().getBytes();
- try {
- dp = new DatagramPacket(buf,buf.length,
- InetAddress.getByName("127.0.0.1"),22525);
- } catch (UnknownHostException e1) {
- e1.printStackTrace();
- }
- try {
- ds.send(dp);
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- //如果发送目的不是广播地址和本机地址则讲发送的内容添加到接收框
- if(!(dp.getAddress().getHostAddress().equals("255.255.255.255"))
- && !(dp.getAddress().getHostAddress().equals("127.0.0.1"))
- && !(dp.getAddress().getHostAddress().equals(InetAddress.getLocalHost()))
- ){
- recvMsg.append("自己: \\r\\n"+sendMsg.getText()+"\\r\\n\\r\\n");
- //System.out.println(InetAddress.getLocalHost());
- }
- sendMsg.setText("");
- }
- //主函数,调用Chat方法
- public static void main(String[] args) {
- new Chat();
- }
- }
- /*
- * 接收信息文本框<br/>
- * 使用多线程,接收框一直在等待信息的到来<br/>
- * */
- class Recv extends JTextArea implements Runnable{
- private static final long serialVersionUID = 1L;
- DatagramSocket ds = null;
- public void run() {
- try {
- ds = new DatagramSocket(22525);
- } catch (SocketException e1) {
- e1.printStackTrace();
- }
- byte[] buf=new byte[1024];
- while(true){
- try{
- DatagramPacket dp=new DatagramPacket(buf,buf.length);
- ds.receive(dp);
- String data = new String(buf,0,dp.getLength());
- String ip = dp.getAddress().getHostAddress();
- int port = dp.getPort();
- String msg = ip+" : "+port+"\\r\\n"+data+"\\r\\n\\r\\n";
- this.append(msg);
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- }
- }
- class TimeLabel extends JLabel implements Runnable{
- private static final long serialVersionUID = 1L;
- /**
- * 覆盖Runnable接口的run()方法,此为该线程要运行的代码<br/>
- * */
- public void run() {
- /**/Calendar cal = Calendar.getInstance();
- int hour = cal.get(Calendar.HOUR_OF_DAY);
- int min = cal.get(Calendar.MINUTE);
- int sec = cal.get(Calendar.SECOND);
- //int hour=0,min=0,sec=0;
- int msec = 0;
- while(true){
- String h,m,s,ms;
- h = hour+"";
- m = min+"";
- s = sec+"";
- ms = msec+"";
- if(msec<10){
- ms = "0"+msec;
- }
- if(sec<10){
- s = "0"+sec;
- }
- if(min<10){
- m = "0"+min;
- }
- this.setHorizontalAlignment(RIGHT);
- //this.setVerticalAlignment(TOP);
- try {
- this.setText("本机地址:"+InetAddress.getLocalHost().getHostAddress()+"//"+"系统时间-"+h+":"+m+":"+s+":"+ms);
- } catch (UnknownHostException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- if(msec==99){
- if(sec==59){
- if(min==59){
- hour++;
- min=0;
- sec=0;
- msec=0;
- }
- else{
- min++;
- sec=0;
- msec=0;
- }
- }
- else{
- sec++;
- msec=0;
- }
- }
- else{
- msec++;
- }
- }
- }
- }
- //该片段来自于http://www.codesnippet.cn/detail/310320149200.html
来源: http://www.codesnippet.cn/detail/310320149200.html