今天在做项目的时候,发现不同子网下是不能做UDP通信的,不知道是不是这样呢
遇到一个错误:eclipse遇到报错:
The type JPEGImageEncoder is not accessible due to restriction on required library C:Javajre1.6.0_07lib t.jar
google后发现用以下方式解决:
这个事eclipse的设置问题,它默认把这些受访问限制的API设成了ERROR,你只要把
Windows-Preferences-Java-Complicer-Errors/Warnings
里面的Deprecated and restricted API中的Forbidden references(access rules)选为Warning就可以编译通过了。
Java UDP服务器代码:
package gui; 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.io.IOException; import java.net.DatagramSocket; import java.net.DatagramPacket; import java.net.InetAddress; public class guiHello extends JFrame implements ActionListener { private static JLabel label = new JLabel("192.168.0.3:8888"); private static JTextArea ta=new JTextArea(30,80); private JFileChooser jfc=new JFileChooser(new File(".")); private JButton bOpen,bSave; private JButton bListen,bOk; 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(bListen, BorderLayout.CENTER); add(panel1); panel2.add(label, BorderLayout.EAST); add(panel2); setLayout(new FlowLayout(FlowLayout.CENTER,10,15)); // add(label); 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+" "; } scan.close(); ta.setText(info); } catch(FileNotFoundException ex){ } } }else if(jbt==bSave){ Save(); }else if(jbt==bListen){ //监听函数须加try catch Runnable tr = new Runnable() { public void run() { try { Listen(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; javax.swing.SwingUtilities.invokeLater(tr); }else{ ta.setText("服务器已开启"); test(); } } //每个按钮对应的函数 private static void Save(){ ta.setText("保存的按钮"); } private static void Listen() throws IOException{ //1、创建DatagramSocket;指明服务器端口 DatagramSocket server = new DatagramSocket(8888); byte[] recvBuf = new byte[1024]; //2、创建数据包,用于接收内容。 DatagramPacket recvPacket = new DatagramPacket(recvBuf , recvBuf.length); //3、接收数据 server.receive(recvPacket); //System.out.println(packet.getData().toString()); //以上语句打印信息错误,因为getData()返回byte[]类型数据,直接toString会将之序列化,而不是提取字符。应该使用以下方法: String recvStr = new String(recvPacket.getData() , 0 , recvPacket.getLength()); System.out.println("Hello World!" + recvStr); int port = recvPacket.getPort(); //地址为InetAddress类型:(为了回发时使用) InetAddress inetAddr = recvPacket.getAddress(); //地址为字符串类型: String strAdd = recvPacket.getAddress().getHostAddress(); ta.setText("监听 到客户机地址:"+strAdd+" 端口:"+port+" 内容:"+recvStr); String sendStr = "Hello ! I'm Server"; byte[] sendBuf; sendBuf = sendStr.getBytes(); DatagramPacket sendPacket = new DatagramPacket(sendBuf , sendBuf.length , inetAddr , port ); server.send(sendPacket); //4、关闭连接。 server.close(); } private static void test(){ ta.setText("测试的按钮:bOk"); } }
Java 客户机代码:
package socket; /*UDP客户端 UDP客户端首先向被动等待联系的服务器发送一个数据报文。一个典型的UDP客户端主要执行下面三步: 1.创建一个DatagramSocket实例,可以选择对本地地址和端口号进行设置。 2.使用DatagramSocket类的send()方法和receive()方法发送和接受DatagramPacket实例,进行通信。 3.通信完成后,使用DatagramSocket类的close()方法来销毁该套接字。 DatagramSocket类的connect()方法确实允许指定远程地址和端口,但该功能是可选的。 */ import java.net.DatagramSocket; import java.net.InetAddress; import java.net.DatagramPacket; public class udpSendTest{ public static void main(String[] args) throws Exception{ //1、创建DatagramSocket用于UDP数据传送。 //DatagramSocket socket = new DatagramSocket(); //本机地址(默认的),任何可用端口 //本机地址(缺点是必须知道,并且必须是本地IP地址),指定本机端口 我方地址和端口 DatagramSocket socket = new DatagramSocket(4567, InetAddress.getByName("192.168.1.103")); //2、创建需要发送的数据包 byte[] buf = "哈利波特之死亡圣器,长岛是没有雪的2的222".getBytes(); //对方地址和端口192.168.0.3 DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.103"), 8888); //3、发送 socket.send(packet); //4、关闭连接 socket.close(); } }