需要做个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();
}

}
}

解决方案 »

  1.   

    你的程序有两个问题。
    其一,多线程共用一个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();
                }
            }
        }}
      

  2.   

    哈哈,楼主不用客气,不过,今天突然想到,我昨天给你改后的代码还是急大的安全问题。
    我虽然在每次读取数据时用:
    packet=new DatagramPacket(receive,receive.length);
    我产生了新的对象。可是,新的对象的数据存放数组还是receive,也就是说,新旧packet都使用receive所指向的堆空间来存放读取数据,这样还是有问题滴。
    应该在上一句前面再加一句:
    receive=new byte[SIZE];
    这样,就万无一失了。
      

  3.   


    while(true){
     byte[] receive=new byte[1024];
     packet=new DatagramPacket(receive,receive.length);
     server_Socket.receive(packet);
    }这样就可以了!因为receive是阻塞式的方法