发送步骤:
使用 DatagramSocket(int port) 建立socket(套间字)服务。
将数据打包到DatagramPacket中去
通过socket服务发送 (send()方法)
关闭资源
import java.io.IOExceptionimport java.net.*
public class Send {
public static void main(String[] args) {
DatagramSocket ds = null //建立套间字udpsocket服务
try {
ds = new DatagramSocket(8999) //实例化套间字,指定自己的port
} catch (SocketException e) {
System.out.println("Cannot open port!")
System.exit(1)
}
byte[] buf= "Hello, I am sender!".getBytes() //数据
InetAddress destination = null
try {
destination = InetAddress.getByName("192.168.1.5") //需要发送的地址
} catch (UnknownHostException e) {
System.out.println("Cannot open findhost!")
System.exit(1)
}
DatagramPacket dp =
new DatagramPacket(buf, buf.length, destination , 10000)
//打包到DatagramPacket类型中(DatagramSocket的send()方法接受此类,注意10000是接受地址的端口,不同于自己的端口!)
try {
ds.send(dp) //发送数据
} catch (IOException e) {
}
ds.close()
}
}
接收步骤:
使用 DatagramSocket(int port) 建立socket(套间字)服务。(我们注意到此服务即可以接收,又可以发送),port指定监视接受端口。
定义一个数据包(DatagramPacket),储存接收到的数据,使用其中的方法提取传送的内容
通过DatagramSocket 的receive方法将接受到的数据存入上面定义的包中
使用DatagramPacket的方法,提取数据。
关闭资源。
import java.net.*
public class Rec {
public static void main(String[] args) throws Exception {
DatagramSocket ds = new DatagramSocket(10000) //定义服务,监视端口上面的发送端口,注意不是send本身端口
byte[] buf = new byte[1024]//接受内容的大小,注意不要溢出
DatagramPacket dp = new DatagramPacket(buf,0,buf.length)//定义一个接收的包
ds.receive(dp)//将接受内容封装到包中
String data = new String(dp.getData(), 0, dp.getLength())//利用getData()方法取出内容
System.out.println(data)//打印内容
ds.close()//关闭资源
}
}
主从Reactor多线程Nio结构,主从Reactor线程模型的特点是:服务端用于接收客户端连接的不再是个1个单独的NIO线程,而是一个独立的NIO线程池。Acceptor接收到客户端TCP连接请求处理完成后(可能包含接入认证等),将新创建的SocketChannel注册到IO线程池(sub reactor线程池)的某个IO线程上,由它负责SocketChannel的读写和编解码工作。Acceptor线程池仅仅只用于客户端的登陆、握手和安全认证,一旦链路建立成功,就将链路注册到后端subReactor线程池的IO线程上,由IO线程负责后续的IO操作。利用主从NIO线程模型,可以解决1个服务端监听线程无法有效处理所有客户端连接的性能不足问题。
它的工作流程总结如下:
从主线程池中随机选择一个Reactor线程作为Acceptor线程,用于绑定监听端口,接收客户端连接;
Acceptor线程接收客户端连接请求之后创建新的SocketChannel,将其注册到主线程池的其它Reactor线程上,由其负责接入认证、IP黑白名单过滤、握手等操作;
步骤2完成之后,业务层的链路正式建立,将SocketChannel从主线程池的Reactor线程的多路复用器上摘除,重新注册到Sub线程池的线程上,用于处理I/O的读写操作。
给你个UDP服务端与客户端的示例:
服务端代码:
import java.net.DatagramPacket
import java.net.InetAddress
import java.net.MulticastSocket
public class UDPMulticastServer {
final static int RECEIVE_LENGTH = 1024
static String multicastHost = "224.0.0.1"
static int localPort = 9998
public static void main(String[] args) throws Exception {
InetAddress receiveAddress = InetAddress.getByName(multicastHost)
if (!receiveAddress.isMulticastAddress()) {// 测试是否为多播地址
throw new Exception("请使用多播地址")
}
int port = localPort
MulticastSocket receiveMulticast = new MulticastSocket(port)
receiveMulticast.joinGroup(receiveAddress)
boolean isStop = false
while(!isStop){
DatagramPacket dp = new DatagramPacket(new byte[RECEIVE_LENGTH], RECEIVE_LENGTH)
receiveMulticast.receive(dp)
String data = new String(dp.getData()).trim()
System.out.println(data)
if("exit".equals(data)){
System.out.println("程序退出")
isStop = true
}
}
receiveMulticast.close()
}
}
客户端代码:
import java.net.DatagramPacket
import java.net.InetAddress
import java.net.MulticastSocket
public class UDPMulticastClient {
static String destAddressStr = "224.0.0.1"
static int destPortInt = 9998
static int TTLTime = 4
public static void main(String[] args) throws Exception {
InetAddress destAddress = InetAddress.getByName(destAddressStr)
if(!destAddress.isMulticastAddress()){//检测该地址是否是多播地址
throw new Exception("地址不是多播地址")
}
int destPort = destPortInt
MulticastSocket multiSocket =new MulticastSocket()
// int TTL = TTLTime
// multiSocket.setTimeToLive(TTL)
byte[] sendMSG = "exit".getBytes()
DatagramPacket dp = new DatagramPacket(sendMSG, sendMSG.length, destAddress , destPort)
multiSocket.send(dp)
multiSocket.close()
}
}
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)