JAVA用UDP实现通信
2017-09-06 17:13
405 查看
本人小白,最近工作用到UDP学习记录一下
服务端:可以接受多个客户端发的请求建立连接
相关方法简单说明
java里udp的通信是由UdpServiceSocket 这个类实现的发送:
如果你想向外发送一个信息需要以下几个方法:DatagramSocket socket = new DatagramSocket();//实例化对象 String serverHost = "127.0.0.1";//地址 int serverPort = 3344;//端口 DatagramPacket dp = new DatagramPacket((name).getBytes(), (name).getBytes().length, InetAddress.getByName(serverHost), serverPort);//向地址端口发送包 socket.send(dp);//发送
接收
DatagramSocket socket = new DatagramSocket(3344);//实例化对象指定监听端口号 byte[] buf =new byte[1024]; DatagramPacket p = new DatagramPacket(buf,buf.length); socket.receive(p);//p里面就有接收到的内容了 该方法会造成阻塞 int port = p.getPort();//对方端口号 String address = p.getAddress().toString();//船端地址(多个/) String message= new String(p.getData()).trim();//信息 getData()取得报文的byte数组编码
关于DatagramPacket
DatagramPacket(byte[] buf, int length, InetAddress addr, int port):从buf数组中,取出length长的数据创建数据包对象,目标是addr地址,port端口。 DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):从buf数组中,取出offset开始的、length长的数据创建数据包对象,目标是addr地址,port端口。 DatagramPacket(byte[] buf, int offset, int length):将数据包中从offset开始、length长的数据装进buf数组。 DatagramPacket(byte[] buf, int length):将数据包中length长的数据装进buf数组。
简单实例:
package com.zzm.test.vast.socket; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class SimpleDemo { public static void receive(){ new Thread(){ @Override public void run() { DatagramSocket socket =null; try { System.out.println("开启服务。。。"); socket = new DatagramSocket(3344); byte[] buffer = new byte[1024]; DatagramPacket p = new DatagramPacket(buffer, buffer.length); System.out.println("开始开启监听。。。"); socket.receive(p);//不断监听的话可以放到while循环中 byte[] data = new byte[p.getLength()]; int port = p.getPort();//对方端口号 String address = p.getAddress().toString();//船端地址(多个/) String message= new String(p.getData()).trim();//信息 getData()取得报文的byte数组编码 System.out.println("Receiver:接收到来自"+address+"端口:"+port+"的消息:" + message); socket.close(); System.out.println("接收完毕关闭receive服务。。。。"); } catch (Exception e) { e.printStackTrace(); 4000 }finally{ if(null!=socket){ socket.close(); } } } }.start(); } public static void send(){ new Thread(){ @Override public void run() { DatagramSocket socket =null; try { socket = new DatagramSocket(); String serverHost = "127.0.0.1";//目标地址是本地地址 int serverPort = 3344;//目标端口 DatagramPacket dp = new DatagramPacket(("你好 recevier").getBytes(), ("你好 recevier").getBytes().length, InetAddress.getByName(serverHost), serverPort); System.out.println("sender:发送消息。。。。"); socket.send(dp);//发送消息时随机选择端口 } catch (Exception e) { e.printStackTrace(); }finally{ if(null!=socket){ socket.close(); System.out.println("发送完毕,关闭send服务"); } } } }.start(); } public static void main(String[] args) { receive(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } send(); } }
控制台输出:
开启服务。。。 开始开启监听。。。 sender:发送消息。。。。 Receiver:接收到来自/127.0.0.1端口:61145的消息:你好 recevier 发送完毕,关闭send服务 接收完毕关闭receive服务。。。。
以下可忽略
本人代码未完待续。。。(由于针对工作的要求是这个么写的:多个地址会向服务端发自己名字,服务端要选择名字向对应的发消息,新手写的不好互喷,大神直接跳过。。)服务端:可以接受多个客户端发的请求建立连接
public class UdpServiceSocket { private DatagramSocket socket ; private Map<String,String[]> ships = new ConcurrentHashMap<String,String[]>();//存放接收到的地址端口号 private boolean flag = false;//是否在循环接受船端信息 true-是,flase-否 Logger logger = LoggerFactory.getLogger(UdpServiceSocket.class); public void setSocket(DatagramSocket socket) { logger.info("UdpServiceSocket 设定 DatagramSocket :"+socket+"........"); this.socket = socket; } public UdpServiceSocket() { } public UdpServiceSocket(int port) { try { socket = new DatagramSocket(port); } catch (SocketException e) { logger.error("socket初始化失败。。。",e); } } public Map<String, String[]> getShips() { return ships; } public void setShips(Map<String, String[]> ships) { this.ships = ships; } public void receive(){ logger.info("开始开启socket接受服务接受信息。。。"); if(null==socket){ logger.error("socket未初始化,开启接受信息失败。。。"); return; } flag = true; new Thread(){ @Override public void run() { try { logger.info("开始接收信息。。。"); while(flag){ byte[] buf =new byte[1024]; DatagramPacket p = new DatagramPacket(buf,buf.length); socket.receive(p); String port = String.valueOf(p.getPort());//端口号 String address = p.getAddress().toString();//地址 if(address.startsWith("/")){ address = address.substring(1); } String shipName = new String(p.getData()).trim();//名 // if(null==ships.get(shipName)){ ships.put(shipName, new String[]{address,port}); // } logger.info("接收到一条信息。。。"+shipName+" "+ships.get(shipName)[0]+" "+ships.get(shipName)[1]); } } catch (IOException e) { logger.error("接受信息异常(可能由close关闭引起)",e); } } }.start(); } public void send(String shipName,String message){ if(null==socket){ logger.error("socket没有初始化,发送信息失败。。。"); return; } new Thread(){ @Override public void run() { try{ logger.info("开始发送信息到。。。"); logger.info("查询目标:"+shipName+"的信息。。。"); String[] ship = ships.get(shipName); String address = null; String port = null; if(null!=ship&&ship.length==2){ address = ship[0]; port = ship[1]; }else{ logger.info("查询无该ip端口信息 ship:"+ship+"发送终止"); return; } DatagramPacket dp = new DatagramPacket(message.getBytes(), message.getBytes().length, InetAddress.getByName(address), Integer.valueOf(port)); socket.send(dp); logger.info("向"+shipName+"信息发送完毕。。。"); return; }catch(Exception e){ logger.error("发送信息到"+shipName+"失败,服务异常",e); return; } } }.start(); } public void close(){ logger.info("关闭接受信息服务。。。"); stopReceive(); try { Thread.sleep(1000); } catch (InterruptedException e) { logger.error("线程sleep异常"+e); } if(null!=socket){ try{ socket.close(); }catch(Exception e){ logger.info("关闭服务,receive可能报错",e); } ships.clear(); } logger.info("关闭接受信息服务成功。。。"); } public boolean isclosed(){ if(null==socket){ return true; } return socket.isClosed(); } public void stopReceive(){//停止循环receive flag = false; } public void startReceive(){ receive(); } public boolean isreceive(){//是否循环receive信息中 return flag; } /** * 启动服务并开始接收 * @param port */ public void start(int port){ try { socket = new DatagramSocket(port); receive();//开始收接 } catch (SocketException e) { logger.error("初始化socket失败。。。",e); } } /** * 手动添加 * @param shipName * @param address * @param port */ public void addShip(String shipName,String address,String port){ ships.put(shipName, new String[]{address,port}); } public void clearShips(){ ships.clear(); } public String getPort(){ if(socket==null){ return ""; } return String.valueOf(socket.getLocalPort()); } public static void main(String[] args) throws InterruptedException{//测试用 UdpServiceSocket s = new UdpServiceSocket(); s.start(3344); // ships.put("hi", new String[]{"127.0.0.1","3344"}); // s.setShips(ships); while(true){ Thread.sleep(3000); s.send("a", "13123131"); s.send("b", "2134234"); // s.send("hi", "message from server"); } } }
相关文章推荐
- Java实现UDP通信
- 使用JAVA实现Socket通信,TCP、UDP简析。
- 安卓PC实现通信与UDP的Java实现
- Java 实现基于 UDP 的简单 socket 通信
- java udp网络编程及实例代码,实现客户端和服务端通信
- [分布式java]基于JavaAPI实现消息方式的系统间通信:UDP/IP+BIO
- Java实现单个客户端与服务器UDP通信
- TCP和UDP 在java上通信上的实现
- 利用Java实现UDP通信
- Java 基于 UDP 实现 Socket中的多客户端通信
- TCP与UDP通信协议及Java实现
- JAVA 多线程实现聊天(UDP通信 )
- Java系列讲座二:Socket网络通信实现聊天软件项目讲解(UDP)
- Java基于UDP实现服务器和多客户端之间的通信
- java网络编程-双线程实现UDP通信
- JAVA系列课程讲座二:使用Socket通信实现简单聊天通信程序(UDP方式)
- Java UDP通信简单实现
- Java 实现简单的UDP通信
- 关于Java的UDP通信连接实现
- Java 基于 UDP 实现 Socket中的多客户端通信