需要做个UDP多线程通信的程序,服务端监听端口,如果接收到消息包,则新建一个线程来处理,我写了测试代码,结果好像不是多线程执行的,而是一个线程结束了,在进行下一个线程,有熟悉多线程的朋友提点下我程序的问题。
serverpublic class UDPServer {
public static final int UDP_PORT=9999;
public static void main(String[] args) {
DatagramSocket server_Socket=null;
DatagramPacket packet=null;
byte[] receive=new byte[1024];
int thread=0;
try {
packet=new DatagramPacket(receive,receive.length);
server_Socket=new DatagramSocket(UDP_PORT);
System.out.println("server start");
} catch (SocketException e) {
e.printStackTrace();
}
while (true) {
if (server_Socket==null) {
break;
}else{
try {
server_Socket.receive(packet);
thread++;
UDPThread udp=new UDPThread(packet,thread);
udp.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}线程类:public class UDPThread extends Thread{
private DatagramPacket packet;
private int thread;
public UDPThread(DatagramPacket udp_Packet,int thread){
this.packet=udp_Packet;
this.thread=thread;
} public void run() {
System.out.println("IP:"+packet.getAddress());
System.out.println("Port:"+packet.getPort());
System.out.println("Content:"+new String(packet.getData()).trim());
for (int i = 0; i < 100; i++) {
System.out.println("我是第"+thread+"个线程在执行");
}
}}clientpublic class UDPClient {
public static void main(String[] args) {
String test_String="测试UDP通信";
byte[] send=test_String.getBytes();
int port=9999;
try {
InetAddress ip=InetAddress.getByName("127.0.0.1");
DatagramPacket packet=new DatagramPacket(send,send.length,ip,port);
DatagramSocket socket=new DatagramSocket();
socket.send(packet);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
serverpublic class UDPServer {
public static final int UDP_PORT=9999;
public static void main(String[] args) {
DatagramSocket server_Socket=null;
DatagramPacket packet=null;
byte[] receive=new byte[1024];
int thread=0;
try {
packet=new DatagramPacket(receive,receive.length);
server_Socket=new DatagramSocket(UDP_PORT);
System.out.println("server start");
} catch (SocketException e) {
e.printStackTrace();
}
while (true) {
if (server_Socket==null) {
break;
}else{
try {
server_Socket.receive(packet);
thread++;
UDPThread udp=new UDPThread(packet,thread);
udp.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}线程类:public class UDPThread extends Thread{
private DatagramPacket packet;
private int thread;
public UDPThread(DatagramPacket udp_Packet,int thread){
this.packet=udp_Packet;
this.thread=thread;
} public void run() {
System.out.println("IP:"+packet.getAddress());
System.out.println("Port:"+packet.getPort());
System.out.println("Content:"+new String(packet.getData()).trim());
for (int i = 0; i < 100; i++) {
System.out.println("我是第"+thread+"个线程在执行");
}
}}clientpublic class UDPClient {
public static void main(String[] args) {
String test_String="测试UDP通信";
byte[] send=test_String.getBytes();
int port=9999;
try {
InetAddress ip=InetAddress.getByName("127.0.0.1");
DatagramPacket packet=new DatagramPacket(send,send.length,ip,port);
DatagramSocket socket=new DatagramSocket();
socket.send(packet);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
其一,多线程共用一个packet。
其二,打印一百行很快,你来不及运行下一个Client。
我将你的程序修改了一下,注意看我加的注释。import java.net.*;
import java.io.*;
public class UDPServer {
public static final int UDP_PORT=9999;
public static void main(String[] args) {
DatagramSocket server_Socket=null;
DatagramPacket packet=null;
byte[] receive=new byte[1024];
int thread=0;
try {
server_Socket=new DatagramSocket(UDP_PORT);
System.out.println("server start");
} catch (SocketException e) {
e.printStackTrace();
}
while (true) {
if (server_Socket==null) {
break;
}else{
try {
//本来你将下面这句代码放在前面,这样会出很大问题。你收到数据包存在
//packet中,用它去初始化一个线程,并让线程运行。可是同时,你又运行
//receive,导致两个线程同时用一个packet,这样存在很大问题。
packet=new DatagramPacket(receive,receive.length);
server_Socket.receive(packet);
thread++;
UDPThread udp=new UDPThread(packet,thread);
udp.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
import java.net.*;
public class UDPThread extends Thread{
private DatagramPacket packet;
private int thread; public UDPThread(DatagramPacket udp_Packet,int thread){
this.packet=udp_Packet;
this.thread=thread;
} public void run() {
System.out.println("IP:"+packet.getAddress());
System.out.println("Port:"+packet.getPort());
System.out.println("Content:"+new String(packet.getData()).trim());
for (int i = 0; i < 10; i++) {
System.out.println("我是第"+thread+"个线程在执行");
try{
//你的程序中,打印一百行。可是我相信,在你运行第二个UDPClient前,一百行
//已经打印完了。看不出效果。所以这里用了sleep
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}}
我虽然在每次读取数据时用:
packet=new DatagramPacket(receive,receive.length);
我产生了新的对象。可是,新的对象的数据存放数组还是receive,也就是说,新旧packet都使用receive所指向的堆空间来存放读取数据,这样还是有问题滴。
应该在上一句前面再加一句:
receive=new byte[SIZE];
这样,就万无一失了。
while(true){
byte[] receive=new byte[1024];
packet=new DatagramPacket(receive,receive.length);
server_Socket.receive(packet);
}这样就可以了!因为receive是阻塞式的方法