您的位置:首页 > 编程语言 > Java开发

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");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: