简单记之,留后用
先实现一对一通信
服务器类
public class UDPServer {
public static void main(String[] args) throws IOException {
/*
* 服务器接收数据
*/
//创建DatagramSockte对象,并指定端口号
DatagramSocket socket=new DatagramSocket(8800);
//设定接收的字节数组,大小可以任意,
byte[] bs=new byte[1024];
//创建数据报,并将接收的数组传入其中,大小为整个数组的长度
DatagramPacket datagramPacket=new DatagramPacket(bs, bs.length);
//接收,相当于监听,直到有数据报,开始响应,并将数据写入到字节数组中
socket.receive(datagramPacket);
//输出字节数组,长度为datagramPacket实际接收的长度
System.out.println("客户端->服务器:"+new String(bs, 0, datagramPacket.getLength()));
/*
* 服务器发送数据
*/
//因为是服务器向客户端发送数据,因此要知道客户端的IP地址,和通信的端口号(通过客户端发送的数据报获得)
InetAddress inet=datagramPacket.getAddress();
int port=datagramPacket.getPort();
//要发送的字节数组
byte[] bs2="welcome".getBytes();
//将IP,端口号,字节数组写入到Datagrampacket对象中
DatagramPacket datagramPacket2=new DatagramPacket(bs2, bs2.length, inet, port);
//发送数据报
socket.send(datagramPacket2);
//最后别忘了关闭DatagramSocket对象
socket.close();
}
}
客户端类
public class UDPClient {
public static void main(String[] args) throws IOException {
/*
* 客户端发送数据
*/
//获取服务器的IP地址,这里是因为服务器就是本机,因此直接使用字符串形式的localhost
InetAddress iAddress=InetAddress.getByName("localhost");
int port=8800;
byte[] bs="登入名:admin;密码:1234".getBytes();
//创建数据报
DatagramPacket datagramPacket=new DatagramPacket(bs, bs.length, iAddress,port);
//创建DatagramSocket对象
DatagramSocket socket=new DatagramSocket();
//使用socket发送数据报
socket.send(datagramPacket);
/*
* 客户端接收数据
*/
//设定接收数据的字节数组
byte[] bs2=new byte[1024];
//创建接收的数据报
DatagramPacket datagramPacket2=new DatagramPacket(bs2, bs2.length);
//将接收的数据报赋给之前创建的数据报对象
socket.receive(datagramPacket2);
//输出数据
System.out.println("服务器->客户端:"+new String(bs2, 0, datagramPacket2.getLength()));
//关闭socket
socket.close();
}
}
多线程通信
给出比较正规的
服务器类
public class UDPServer {
private static int j=0;
public static void main(String[] args) throws IOException {
/*
* 服务器接收数据
*/
//创建DatagramSockte对象,并指定端口号
DatagramSocket socket=new DatagramSocket(8800);
//设定接收的字节数组,大小可以任意,
byte[] bs=new byte[1024];
//接收,相当于监听,直到有数据报,开始响应,并将数据写入到字节数组中
while(true){
//创建数据报,并将接收的数组传入其中,大小为整个数组的长度
DatagramPacket packet=new DatagramPacket(bs, bs.length);
socket.receive(packet);
UDPServerThread serverThread=new UDPServerThread(socket,packet);
serverThread.start();
}
}
服务器线程类
public class UDPServerThread extends Thread{
DatagramSocket socket=null;
DatagramPacket packet=null;
private static int i=0;
public UDPServerThread(DatagramSocket socket,DatagramPacket packet) {
// TODO Auto-generated constructor stub
this.socket=socket;
this.packet=packet;
}
@Override
public void run() {
//接收数据
byte[] bs=packet.getData();
//输出字节数组,长度为datagramPacket实际接收的长度
System.out.println("客户端->服务器:"+new String(bs, 0, packet.getLength()));
/*
* 服务器发送数据
*/
//因为是服务器向客户端发送数据,因此要知道客户端的IP地址,和通信的端口号(通过客户端发送的数据报获得)
InetAddress inet=packet.getAddress();
int port=packet.getPort();
//要发送的字节数组
byte[] bs2=("welcome"+(++i)).getBytes();
//将IP,端口号,字节数组写入到Datagrampacket对象中
DatagramPacket datagramPacket2=new DatagramPacket(bs2, bs2.length, inet, port);
//发送数据报
try {
socket.send(datagramPacket2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//最后别忘了关闭DatagramSocket对象
// socket.close();
}
}
这里我之前在写的时候,出现了一个很奇妙的问题,我找了好久,错误代码如下
public static void main(String[] args) throws IOException {
//创建DatagramSockte对象,并指定端口号
DatagramSocket socket=new DatagramSocket(8800);
//设定接收的字节数组,大小可以任意,
byte[] bs=new byte[1024];
//创建数据报,并将接收的数组传入其中,大小为整个数组的长度
DatagramPacket packet=new DatagramPacket(bs, bs.length);
//接收,相当于监听,直到有数据报,开始响应,并将数据写入到字节数组中
while(true){
socket.receive(packet);
UDPServerThread serverThread=new UDPServerThread(socket,packet);
serverThread.start();
}
}
因为DatagramPacket对象只有一个,每当new一个线程的时候,主线程里面就进入receive的堵塞状态,而且占据着这唯一的DatagramPacket对象,因此子线程中就不能够使用该对象,
后面意识到后,加了一句serverThread.join(); 目的是让子线程先执行完后,主线程才开始进行堵塞状态,然后问题就解决了,但是这样会比前面介绍的运行慢