java udp 广播及socket通讯
UDP通讯
udp 是一种网络通信协议,不需要客户端和服务器端建立连接即可进行通讯功能。相对于Tcp协议它有着tcp用很多优点,例如广播功能。udp的广播功能可以指定特定网段进行广播内容,而无需知道接收者是谁,只有接受者在广播范围内即可接收广播内容。其实基于这个功能可以实现一个局域网群聊室的功能。
udp广播发送有两种形式,
方式一:通过DatagramSocket实现
方式二:通过MulticastSocket 实现
方式一:demo;
1,数据发送端:
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 SendIP { public static void main(String args[]) { new SendIP().lanchApp(); } private void lanchApp(){ SendThread th=new SendThread(); th.start(); } private class SendThread extends Thread{ @Override public void run() { while(true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } try { BroadcastIP(); } catch (Exception e) { e.printStackTrace(); } } } private void BroadcastIP()throws Exception{ DatagramSocket dgSocket=new DatagramSocket(); byte b[]="你好,这是我发给你的消息".getBytes(); DatagramPacket dgPacket=new DatagramPacket(b,b.length,InetAddress.getByName("255.255.255.255"),8989); dgSocket.send(dgPacket); dgSocket.close(); System.out.println("send message is ok."); } } }
2,数据接收端:
import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SearchIP{ public static void main(String args[])throws Exception{ new SearchIP().lanchApp(); } private void lanchApp(){ receiveThread th=new receiveThread(); th.start(); } private class receiveThread extends Thread{ @Override public void run() { while(true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } try { receiveIP(); } catch (Exception e) { e.printStackTrace(); } } } private void receiveIP() throws Exception{ DatagramSocket dgSocket=new DatagramSocket(8989); byte[] by=new byte[1024]; DatagramPacket packet=new DatagramPacket(by,by.length); dgSocket.receive(packet); String str=new String(packet.getData(),0,packet.getLength()); System.out.println("接收到数据大小:"+str.length()); System.out.println("接收到的数据为:"+str); dgSocket.close(); System.out.println("recevied message is ok."); } } }
整合封装一个类管理:
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; public class NetClient { String ip; private int udp_port; private DatagramSocket ds=null; public void connect(String ip,int port){ this.ip=ip; this.udp_port=port; try { ds=new DatagramSocket(udp_port); } catch (SocketException e1) { e1.printStackTrace(); } new Thread(new UDPThread()).start(); } private class UDPThread implements Runnable{ byte[] buf=new byte[1024]; @Override public void run() { while(ds!=null){ DatagramPacket dp=new DatagramPacket(buf, buf.length); try { ds.receive(dp); parse(dp); System.out.println("receive a package from server"); } catch (IOException e) { e.printStackTrace(); } } } private void parse(DatagramPacket dp) { ByteArrayInputStream bais = new ByteArrayInputStream(buf, 0, dp.getLength()); DataInputStream dis = new DataInputStream(bais); String msg=null; try { msg=dis.readUTF(); } catch (IOException e) { e.printStackTrace(); } } } /** * send data package to server * @param ds * @param ip * @param udpPort */ public void sendMsg(String str) { if(ds==null) return; ByteArrayOutputStream baos=new ByteArrayOutputStream(); DataOutputStream dos=new DataOutputStream(baos); try { dos.write(str.getBytes("UTF-8")); dos.flush(); } catch (IOException e) { e.printStackTrace(); } byte[] buf=baos.toByteArray(); try { DatagramPacket dp=new DatagramPacket(buf, buf.length, new InetSocketAddress(ip, udp_port)); ds.send(dp); } catch (SocketException e) { Log.e("udpmsg", e.getMessage()); } catch (IOException e) { Log.e("udpmsg", e.getMessage()); } }
方式二demo;
1,数据发送端:
import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; public class MulBroadcast extends Thread{ String info ="节目预告: 恭喜您中500w彩票了"; int port =9898; InetAddress address; MulticastSocket socket; public MulBroadcast(){ try{ address=InetAddress.getByName("233.0.0.0"); socket=new MulticastSocket(port); socket.setTimeToLive(1); socket.joinGroup(address); }catch(IOException e){ e.printStackTrace(); } } @Override //最简单的方法也就是建立一个线程来运行 public void run(){ while(true){ byte[] data=info.getBytes(); DatagramPacket packet=new DatagramPacket(data,data.length,address,port); try { socket.send(packet); Thread.sleep(3000); } catch (Exception e) { e.printStackTrace(); } System.out.println("消息已发送:"); } } public static void main(String[] args){ new MulBroadcast().start(); } }
2,数据接收端:
import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; public class MulReceiverIP extends Thread{ int port=9898; InetAddress group; MulticastSocket socket; //socket sends and receives the packet. DatagramPacket packet; byte[] buf=new byte[30];// If the message is longer than the packet's length, the message is truncated. public MulReceiverIP(){ try { socket=new MulticastSocket(port); group=InetAddress.getByName("233.0.0.0"); socket.joinGroup(group); //加入广播组,加入group后,socket发送的数据报,可以被加入到group中的成员接收到。 packet=new DatagramPacket(buf,buf.length); } catch (IOException e) { e.printStackTrace(); } } @Override public void run(){ while(true){ try { socket.receive(packet); } catch (IOException e) { e.printStackTrace(); } // String message=new String(buf); String message=new String(packet.getData(),0,packet.getLength());//very important !! System.out.println("接受消息内容: "+message); } } public static void main(String[] args) { new MulReceiverIP().start(); } }
Socket通讯
Android中sockect通讯实质属于Java socket通讯,在Java.NET目录下,主要可分为基于tcp协议socket和基于udp协议的DatagramSocket两个方向网络通讯还离不开输入,输出流的处理 在 java.io/java.nio目录下,其中对于输入输出流的选择,主要看情况选择合适的流进行封装处理。这里我选择的是DataOutputStream ,DataInputStream主要是因为它们可以直接读取和写入基本数据类型方法,省去转换类型的麻烦。
class Client{ public static final int port=8882; private Socket s=null; private String str=null; private DataOutputStream dos=null; private DataInputStream dis=null; private boolean bconn=false; private Thread th; public Client(String ip){ th=new Thread(new Received()); connect(ip); th.start(); } private void send_msg(){ try { dos=new DataOutputStream(s.getOutputStream()); dos.writeUTF(str); dos.flush(); } catch (IOException e) { e.printStackTrace(); } } public void connect(String ip){ try { s=new Socket(ip, port); bconn=true; dis=new DataInputStream(s.getInputStream()); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void release_dis(){ try { bconn=false; if(dos!=null){ dos.close(); dos=null; } if(dis!=null){ dis.close(); dis=null; } if(s!=null){ s.close(); s=null; } } catch (IOException e) { e.printStackTrace(); } } private class Received implements Runnable{ @Override public void run() { try { while(bconn){ String msg=dis.readUTF(); Log.e("read msg", msg); } } catch(SocketException e){ Log.e("quit msg", "has quit"); }catch (IOException e) { e.printStackTrace(); } } } }