波神

导航

java socket 之UDP编程

一、概念

        在TCP的所有操作中都必须建立可靠的连接,这样一来肯定会浪费大量的系统性能,为了减少这种开销,在网络中又提供了另外的一种传输协议——UDP,不可靠的连接(这种协议在各种聊天工具中被广泛使用)。
       在UDP程序的开发中使用DatagramPacket包装一条要发送的信息,之后使用DatagramSocket用于完成信息的发送操作。
例如:现在使用聊天工具进行聊天,那么A发送的信息B不一定能够接收的到,因为使用的就是UDP协议。

基于UDP通信的基本模式:

(1)将数据打包,称为数据包(好比将信件装入信封一样),然后将数据包发往目的地。

(2)接受别人发来的数据包(好比接收信封一样),然后查看数据包中的内容。

以下用一个聊天程序来说明,功能效果如下图所示:

二、工程目录

三、服务端

1)UDPServer类,服务端主类

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;


public class UDPServer extends JFrame implements ActionListener{
    
    JTextArea jta;
    JTextField jtf;
    JButton jb;
    JPanel jp;    
    ServerToClientThread stcT;
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new UDPServer();
    }
    
    public UDPServer()
    {
        setTitle("UDP服务端");
        jta=new JTextArea();
        jtf=new JTextField(15);
        jb=new JButton("发送");
        jb.addActionListener(this);
        
        jp=new JPanel();
        jp.add(jtf);
        jp.add(jb);
        
        this.add(jta,"Center");
        this.add(jp,"South");
        this.setBounds(300, 200, 300, 200);
        this.setVisible(true);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        stcT = new ServerToClientThread(jta);
        stcT.start();
        
        /**窗体关闭按钮事件*/
        this.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                if(JOptionPane.showConfirmDialog(null, "<html>确定退出吗?","系统提示",JOptionPane.OK_CANCEL_OPTION,JOptionPane.INFORMATION_MESSAGE)==0)
                {        
                    System.exit(0);
                    stcT.closeSocket();
                }
                else
                {
                    return;
                }
            }
        });
    }
    
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub
        //假如点击了按钮jb
        if(arg0.getSource()==jb)
        {            
            byte buffer[] = jtf.getText().trim().getBytes();
            stcT.sendData(buffer);
        }
        
    }

}

2)ServerToClientThread类,服务端处理线程

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

import javax.swing.JTextArea;

/**
 * @author lenovo
 *
 */
public class ServerToClientThread extends Thread{

    private String sendIP = "127.0.0.1";    
    private int sendPORT = 6666;
    private int receivePORT = 8888;
    //声明发送信息的数据报套结字
    private DatagramSocket sendSocket = null;
    //声明发送信息的数据包
    private DatagramPacket sendPacket = null;
    //声明接受信息的数据报套结字
    private DatagramSocket receiveSocket = null;
    //声明接受信息的数据报
    private DatagramPacket receivePacket = null;


    //缓冲数组的大小
    public static final int BUFFER_SIZE = 5120;
    private byte inBuf[] = null; //接收数据的缓冲数组
    
    JTextArea jta;
    
    // 构造函数
    public ServerToClientThread(JTextArea jta) {
        this.jta = jta;
    }

    public void run() {
        try{
            inBuf = new byte[BUFFER_SIZE];
            receivePacket = new DatagramPacket(inBuf,inBuf.length);
            receiveSocket = new DatagramSocket(receivePORT);
        }catch (Exception e) {
            e.printStackTrace();
            // TODO: handle exception
        }
        
        while (true) {
            if(receiveSocket == null){
                break;
            } else {
                try {
                    receiveSocket.receive(receivePacket);
                    String message = new String(receivePacket.getData(),0,receivePacket.getLength());
                    jta.append("收到数据"+message+"\n");
                } catch (Exception e) {
                    e.printStackTrace();
                    // TODO: handle exception
                }
            }
        }
    }

    public void sendData(byte buffer[]){
        try{
            InetAddress address = InetAddress.getByName(sendIP);
        //    outBuf = new byte[BUFFER_SIZE];
            sendPacket = new DatagramPacket(buffer,buffer.length,address,sendPORT);
            sendSocket = new DatagramSocket();
            sendSocket.send(sendPacket);
        }catch (Exception e) {
            e.printStackTrace();
            // TODO: handle exception
        }
    }
    public void closeSocket(){
        receiveSocket.close();
    }
}

三、客户端

1)UDPClient类,客户端主类

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

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


public class UDPClient extends JFrame implements ActionListener{
    
    JTextArea jta;
    JTextField jtf;
    JButton jb;
    JPanel jp;
    ClientToServerThread ctsT;
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new UDPClient();
    }
    
    public UDPClient()
    {
        setTitle("UDP客户端");
        jta=new JTextArea();
        jtf=new JTextField(15);
        jb=new JButton("发送");
        jb.addActionListener(this);
        
        jp=new JPanel();
        jp.add(jtf);
        jp.add(jb);
        
        this.add(jta,"Center");
        this.add(jp,"South");
        this.setBounds(300, 200, 300, 200);
        this.setVisible(true);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        ctsT = new ClientToServerThread(jta);
        ctsT.start();
        
        /**窗体关闭按钮事件*/
        this.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                if(JOptionPane.showConfirmDialog(null, "<html>确定退出吗?","系统提示",JOptionPane.OK_CANCEL_OPTION,JOptionPane.INFORMATION_MESSAGE)==0)
                {        
                    System.exit(0);
                    ctsT.closeSocket();
                }
                else
                {
                    return;
                }
            }
        });
    }
    
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub
        //假如点击了按钮jb
        if(arg0.getSource()==jb)
        {            
            byte buffer[] = jtf.getText().trim().getBytes();
            ctsT.sendData(buffer);
        }
        
    }

}

2)ClientToServerThread类,客户端线程处理类

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


import javax.swing.JTextArea;

/**
 * @author lenovo
 *
 */
public class ClientToServerThread extends Thread{

    private String sendIP = "127.0.0.1";
    private int sendPORT = 8888;
    private int receivePORT = 6666;
    //声明发送信息的数据报套结字
    private DatagramSocket sendSocket = null;
    //声明发送信息的数据包
    private DatagramPacket sendPacket = null;
    //声明接受信息的数据报套结字
    private DatagramSocket receiveSocket = null;
    //声明接受信息的数据报
    private DatagramPacket receivePacket = null;

    
    //缓冲数组的大小
    public static final int BUFFER_SIZE = 5120;

    private byte inBuf[] = null; //接收数据的缓冲数组
    
    JTextArea jta;
    
    // 构造函数
    public ClientToServerThread(JTextArea jta) {
        this.jta = jta;
    }

    public void run() {
        try{
            inBuf = new byte[BUFFER_SIZE];
            receivePacket = new DatagramPacket(inBuf,inBuf.length);
            receiveSocket = new DatagramSocket(receivePORT);
        }catch (Exception e) {
            e.printStackTrace();
            // TODO: handle exception
        }
        
        while (true) {
            if(receiveSocket == null){
                break;
            } else {
                try {
                    receiveSocket.receive(receivePacket);
                    String message = new String(receivePacket.getData(),0,receivePacket.getLength());
                    jta.append("收到数据"+message+"\n");
                } catch (Exception e) {
                    e.printStackTrace();
                    // TODO: handle exception
                }
            }
        }
    }
    
    public void sendData(byte buffer[]){
        try{
            InetAddress address = InetAddress.getByName(sendIP);
            sendPacket = new DatagramPacket(buffer,buffer.length,address,sendPORT);
            //注意发送的时候,socket不需要绑定地址
            sendSocket = new DatagramSocket();
            sendSocket.send(sendPacket);
        }catch (Exception e) {
            e.printStackTrace();
            // TODO: handle exception
        }
    }
    public void closeSocket(){
        receiveSocket.close();
    }
}

 

posted on 2016-09-22 10:01  波神  阅读(583)  评论(0编辑  收藏  举报