udp服务器监听(多线程)

项目一:udp1111

监听的有三个文件分别为:

guiHello.java 有关界面和事件响应功能

UdpFunc.java是udp类的封装:发送和接收

udpServer.java是入口函数,无实际意义

代码:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.Scanner;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
////

import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;


public class guiHello extends JFrame implements ActionListener {
    
     private static  UdpFunc func; //全局变量:调用udp类的实例化
     private static boolean status;       //侦听状态改变标志位
     private static JLabel label = new JLabel("192.168.0.3:5050");
     private static JTextArea ta=new JTextArea(30,80);
     private JFileChooser jfc=new JFileChooser(new File("."));
     private JButton bOpen,bSave;
     private JButton bListen,bOk,bStop;
     public guiHello()
     {
         super("UDP监听GUI");
         JScrollPane ps=new JScrollPane(ta);
         bOpen=new JButton("选取源文件");
         bSave=new JButton("保存变量"); 
         bListen = new JButton("开始监听");   //这个是自定义的按钮
         bOk     = new JButton("测试按钮"); 
        
        //自定义两个 JPanel       
         JPanel panel1 = new JPanel(new BorderLayout());
         JPanel panel2 = new JPanel(new BorderLayout());
         
         //两个panel第二个背景为红色
         panel2.setBackground(Color.red);
         //panel1.add(bStop, BorderLayout.WEST);
         panel1.add(bListen, BorderLayout.CENTER);
         
         add(panel1);
         panel2.add(label, BorderLayout.EAST);
         add(panel2);
         
         setLayout(new FlowLayout(FlowLayout.CENTER,10,15));
         
         add(ps);
         add(bOpen);
         add(bSave);
        // add(bListen);
         add(bOk);
         Border b = new LineBorder(Color.ORANGE, 2);
         bListen.setBorder(b);
         bOpen.addActionListener(this);
         bSave.addActionListener(this);
         bListen.addActionListener(this);
         bOk.addActionListener(this);
         
         setVisible(true);
         setSize(1600,1500);
         
     }
   /* public static void main(String[] args) {
        // TODO Auto-generated method stub
        guiHello frm=new guiHello();
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
}
    */
    public void actionPerformed(ActionEvent e)
    {
        JButton jbt=(JButton)e.getSource();
        if(jbt==bOpen)
        {
            int status=jfc.showOpenDialog(this);
            if(status!=JFileChooser.APPROVE_OPTION)
                ta.setText("没有选择文件");
            else {
                try{
                    File file1=jfc.getSelectedFile();
                    Scanner scan=new Scanner(file1);
                    String info="";
                    while(scan.hasNext())
                    {
                        String str=scan.nextLine();
                        info+=str+"\r\n";
                    }
                    scan.close();
                    ta.setText(info);
                }
                catch(FileNotFoundException ex){
            
                }
                }
            
            
       }else if(jbt==bSave){
           Save();
          
       }else if(jbt==bListen){
           ta.setText("开始监听...");
           status =true;    //开始监听时为truejbt==bStop
           func = new UdpFunc(5050);
            new Thread(new Logic()).start();
           
       }else if(e.getActionCommand().equals("测试按钮")){
           
              ta.setText("按钮bOk");
             
           
       }else{
           ta.setText("未注册变量");
       }
    }
    
    //每个按钮对应的函数
    private static void Save(){
         ta.setText("保存的按钮");
         
    }
    
  
    
  /*
    * 逻辑类,主要负责接收报文并显示出来
    * 
    * @author ghost
    * 
    */
  private static class Logic implements Runnable {

       public void run() {
           //由于类为static,所以监听标志位也为静态变量,根据true flase决定监听线程是否一直开启
           while (true) {
               String message = func.read();
               //System.out.println(message);
               ta.setText(message);
              
           }
          
       }

   }

}
guiHello.java
 
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
 
public class UdpFunc {
     
    DatagramSocket udp;
     
    /**
     * 在指定端口监听udp消息
     * @param port
     */
    UdpFunc(int port) {
        try {
            udp=new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
     
    /**
     * 向指定的ip地址的端口发送消息
     * @param message 要发送的消息
     * @param port 指定的端口
     * @param ip 指定的ip地址
     */
    void send(String message,int port,String ip) {
        try {
            byte temp[]=message.getBytes();
            InetAddress address=InetAddress.getByName(ip);
            DatagramPacket send_packet=new DatagramPacket(temp,temp.length,address,port);
            udp.send(send_packet);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
     
    /**
     * 从端口读取报文并返回报文数据
     * @return 报文数据
     */
    String read() {
        byte temp[]=new byte[2048];
        DatagramPacket receive_packet=new DatagramPacket(temp,temp.length);
        try {
            udp.receive(receive_packet);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String result=new String(receive_packet.getData(),0,receive_packet.getLength());
        return result;
    }
}
UdpFunc.java
import javax.swing.JFrame;


public class udpServer {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // 开启GUI面板,打开侦听函数
        guiHello frm=new guiHello();
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

}
udpServer.java

 

项目二:udpChat

参考代码:

一个简易的udp聊天工具:

UdpFunc.java 是udp类的封装:发送和接收

UdpGui.java  GUI及对数据处理

代码:

package com.ghost.chat.udp;
 
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
 
public class UdpFunc {
     
    DatagramSocket udp;
     
    /**
     * 在指定端口监听udp消息
     * @param port
     */
    UdpFunc(int port) {
        try {
            udp=new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
     
    /**
     * 向指定的ip地址的端口发送消息
     * @param message 要发送的消息
     * @param port 指定的端口
     * @param ip 指定的ip地址
     */
    void send(String message,int port,String ip) {
        try {
            byte temp[]=message.getBytes();
            InetAddress address=InetAddress.getByName(ip);
            DatagramPacket send_packet=new DatagramPacket(temp,temp.length,address,port);
            udp.send(send_packet);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
     
    /**
     * 从端口读取报文并返回报文数据
     * @return 报文数据
     */
    String read() {
        byte temp[]=new byte[2048];
        DatagramPacket receive_packet=new DatagramPacket(temp,temp.length);
        try {
            udp.receive(receive_packet);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String result=new String(receive_packet.getData(),0,receive_packet.getLength());
        return result;
    }
}
UdpFunc.java
package com.ghost.chat.udp;
 
import java.awt.BorderLayout;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
 
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;
 
public class UdpGui extends JFrame {
 
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
 
    private JTextField jtf_port;  //服务器端口(也就是启动监听时服务器开的端口)
    private JTextField jtf_other_port; //other表示发送给一个电脑:端口为:jtf_other_port
    private JTextField jtf_other_ip;   //                  ip为:jtf_other_ip
    private JButton btn_start;
    private JTextArea jta_message;
    private JTextField jtf_message;
    private JButton btn_send;
    private List jl_list;
    private UdpFunc func;
    private boolean status;
 
    UdpGui() {
        super("UDP");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        guiInitialization();
        actionInitialization();
        this.setVisible(true);
    }
 
    /**
     * 注册事件响应函数
     */
    private void actionInitialization() {
 
        jtf_message.setEditable(false);
        btn_send.setEnabled(false);
        jl_list.setVisible(false);
 
        btn_start.addActionListener(new ActionListener() {
 
            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().equals("start")) {
                    int port = Integer.parseInt(jtf_port.getText());
                    func = new UdpFunc(port);//服务器端口
                    status = true;
                    new Thread(new Logic()).start();
                    postMessage("启动UDP服务器(" + port + ")");
                    btn_start.setText("stop");
                    jtf_port.setEditable(false);
                    jtf_other_ip.setEditable(false);
                    jtf_other_port.setEditable(false);
                    jtf_message.setEditable(true);
                    btn_send.setEnabled(true);
                } else if (e.getActionCommand().equals("stop")) {
                    status = false;
                    postMessage("服务器已经停止运行");
                    btn_start.setText("start");
                    jtf_port.setEditable(true);
                    jtf_other_ip.setEditable(true);
                    jtf_other_port.setEditable(true);
                    jtf_message.setText("");
                    jtf_message.setEditable(false);
                    btn_send.setEnabled(false);
                } else {
                    postMessage("发生未注册事件,请验证程序是否被修改");
                }
            }
 
        });
 
        btn_send.addActionListener(new ActionListener() {
 
            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().equals("send")) {
                    String message = jtf_message.getText();
                    if (message.trim().equalsIgnoreCase("")) {
                        postMessage("警告:" + "你不能发送空字符串");
                    } else {
                        func.send(message,
                                Integer.parseInt(jtf_other_port.getText()),//发送给客户机,需指定端口和IP
                                jtf_other_ip.getText());
                        postMessage("我:" + message);
                    }
                    jtf_message.setText("");
                    jtf_message.requestFocus();
                } else {
                    postMessage("发生未注册事件,请验证程序是否被修改");
                }
            }
 
        });
 
        jtf_message.addActionListener(new ActionListener() {
 
            public void actionPerformed(ActionEvent e) {
                String message = jtf_message.getText();
                if (message.trim().equalsIgnoreCase("")) {
                    postMessage("警告:" + "你不能发送空字符串");
                } else {
                    func.send(message,
                            Integer.parseInt(jtf_other_port.getText()),
                            jtf_other_ip.getText());
                    postMessage("自己:" + message);
                }
                jtf_message.setText("");
                jtf_message.requestFocus();
            }
 
        });
 
    }
 
    /**
     * 得到当前系统时间
     * 
     * @return 当前系统时间
     */
    String getTime() {
        Date date = new Date();
        SimpleDateFormat formater = new SimpleDateFormat("HH:mm:ss");
        return formater.format(date);
    }
 
    /**
     * 向GUI界面递送显示的消息
     * 
     * @param message
     *            要显示在界面上的消息(会自动加上当前系统时间)
     */
    void postMessage(String message) {
        if (jta_message.getLineCount() > 500) {
            jta_message.setText("time:" + getTime() + " " + "消息过多,执行自动清理...\n");
        }
        jta_message.append("time:" + getTime() + " " + message + "\n");
        jta_message.requestFocus();
        jta_message.setCaretPosition(jta_message.getText().length());
    }
 
    /**
     * 初始化界面
     */
    private void guiInitialization() {
        this.setSize(800, 600);
        this.setLocation(400, 200);
        this.setResizable(false);
        JPanel container = new JPanel();
        this.add(container);
        container.setLayout(new BorderLayout());
        JPanel header = new JPanel();
        header.add(new JLabel("服务器端口:"));
        jtf_port = new JTextField("5050", 4);
        header.add(jtf_port);
        header.add(new JLabel("待发送客户机端口:"));
        jtf_other_port = new JTextField("5000", 4);
        header.add(jtf_other_port);
        header.add(new JLabel("待发送客户机IP:"));
        jtf_other_ip = new JTextField("192.168.1.108", 10); //127.0.0.1
        header.add(jtf_other_ip);
        btn_start = new JButton("start");
        header.add(btn_start);
        JPanel main = new JPanel();
        jta_message = new JTextArea();
        jta_message.setAutoscrolls(true);
        jta_message.setEditable(false);
        JScrollPane scorllPanel = new JScrollPane(jta_message);
        scorllPanel
                .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scorllPanel
                .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        main.setLayout(new BorderLayout());
        main.add(scorllPanel, BorderLayout.CENTER);
        JPanel bottom = new JPanel();
        jtf_message = new JTextField("", 25);
        btn_send = new JButton("send");
        bottom.add(new JLabel("Send:"));
        bottom.add(jtf_message);
        bottom.add(btn_send);
        JPanel right = new JPanel();
        right.setLayout(new BorderLayout());
        jl_list = new List();
        right.add(jl_list, BorderLayout.CENTER);
        container.add(header, BorderLayout.NORTH);
        container.add(main, BorderLayout.CENTER);
        container.add(bottom, BorderLayout.SOUTH);
        container.add(right, BorderLayout.EAST);
    }
 
    /**
     * 逻辑类,主要负责接收报文并显示出来
     * 
     * @author ghost
     * 
     */
    private class Logic implements Runnable {
 
        public void run() {
            while (status) {//true
                String message = func.read();
                System.out.println(message);
                postMessage("对方:" + message);
            }
        }
 
    }
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new UdpGui();
    }
 
}
UdpGui.java

 

自己利用项目一作为服务器,项目二作为客户端(实际上,也可以作为服务器),发送检验:

 

代码,上传上来,项目名为udp1111,udpchat,以供后续使用

 

posted @ 2015-11-11 13:20  平常心,平常心  阅读(2995)  评论(0编辑  收藏  举报