java中的简单Udp通讯程序

前言

原创文章欢迎转载,请保留出处。
若有任何疑问建议,欢迎回复。
邮箱:[email protected]

本人学习java中的socket练手的小程序,高手请飘过,仅作为学习笔记,没有技术含量。


分析

这里使用两个独立线程负责发包和收包,设计两个类实现Runnable接口,利用管道和主窗体通信。


代码

mainfest.txt文件这里注意有myqq.MyQQ后的回车符和myqq.MyQQ前的空格

Main-Class: myqq.MyQQ

MyQQ.java文件

package myqq;

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

class UdpSend implements Runnable
{
    private DatagramSocket ds;
    private InputStream is;
    public UdpSend(DatagramSocket ds,InputStream is)
    {
        try
        {
            this.ds = ds;
            this.is = is;
        }
        catch (Exception e)
        {
            throw new RuntimeException("发送端错误");
        }
    }
    public void run()
    {
        try
        {   
            //读取来自文本框的数据
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String s = null;
            while((s=br.readLine())!=null)
            {
                //当输入886时停止发送数据
                if("886".equals(s))
                    break;

                byte[] buf  = s.getBytes();

                //这里是要发送数据包的目标ip和端口,也可以设置成广播地址
                DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("169.254.255.255"),12345);
                ds.send(dp);
            }
            br.close();

            ds.close();
        }
        catch (Exception e)
        {
            throw new RuntimeException("发送端错误");
        }


    }
}

class UdpRecv implements Runnable
{
    private DatagramSocket ds;
    private OutputStream is;

    public UdpRecv(DatagramSocket ds,OutputStream is)
    {
        try
        {
            this.ds = ds;
            this.is = is;
        }
        catch (Exception e)
        {
            throw new RuntimeException("接收端错误");
        }
    }

    public void run()
    {
        try
        {
            while(true)
            {
                //Udp最大的数据包长度是64k
                byte[] buf = new byte[1024*64];

                DatagramPacket dp = new DatagramPacket(buf,buf.length);

                ds.receive(dp);

                //获取数据包的源ip和数据内容
                String ip = dp.getAddress().getHostAddress();
                String data = new String(dp.getData(),0,dp.getLength());

                String s = ip+"::"+data;

                is.write(s.getBytes());
                is.flush();
            }   
        }
        catch (Exception e)
        {
            throw new RuntimeException("接收端错误");
        }


    }
}


class MyQQ 
{
    private static Frame r;
    private static TextArea tsend;//发送文本框
    private static TextArea trecv;//接收文本框

    //发送通信管道
    private static PipedInputStream sis;
    private static PipedOutputStream sos;

    //接收通信管道
    private static PipedInputStream ris;
    private static PipedOutputStream ros;

    public static void main(String[] args) throws Exception
    {
        DatagramSocket sendds = new DatagramSocket();
        DatagramSocket recvds = new DatagramSocket(12345);//监听的端口

        sis = new PipedInputStream();
        sos = new PipedOutputStream();
        sis.connect(sos);

        ris = new PipedInputStream();
        ros = new PipedOutputStream();
        ris.connect(ros);

        //启动发送和接收线程
        new Thread(new UdpRecv(recvds,ros)).start();
        new Thread(new UdpSend(sendds,sis)).start();

        System.out.println("Hello MyQWQ!");

        init();

        while(true)
        {
            byte[] buf = new byte[1024];
            int len = ris.read(buf);

            trecv.append(new String(buf,0,len)+"\r\n");
        }


    }

    public static void init() throws IOException
    {
        r = new Frame("MyQQ");

        trecv = new TextArea("",20,50,TextArea.SCROLLBARS_VERTICAL_ONLY);
        tsend = new TextArea("",13,50,TextArea.SCROLLBARS_VERTICAL_ONLY);

        r.setBounds(400,100,400,600);
        r.setLayout(new FlowLayout());


        r.add(trecv);
        r.add(tsend);

        //Frame事件
        event();

        r.setVisible(true);

        //设置输入框为当前焦点
        trecv.transferFocus();

    }

    public static void event()
    {
        r.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });

        tsend.addKeyListener(new KeyAdapter()
        {
            public void keyPressed(KeyEvent e)
            {
                if(e.getKeyCode()==KeyEvent.VK_ENTER)//回车键发送数据
                {
                    e.consume();
                    try
                    {
                        sos.write((tsend.getText()+"\r\n").getBytes());
                        sos.flush();
                        //System.out.println(tsend.getText());
                    }
                    catch (Exception ex)
                    {
                        throw new RuntimeException("IO错误");
                    }
                    tsend.setText("");
                }
            }
        }); 
    }
}


编译和打包

到文件目录下编译,也可以使用IDE建工程

javac -d . MyQQ.java
jar cvfm myqq.jar mainfest.txt myqq

运行效果

直接运行打包的myqq.jar:(由于只有一台电脑,地址写的是广播地址,能收到证明程序成功发出并收到包)
技术分享

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。