UDP編程,使用多線程的時候為什么在run方法中獲取不到值?
如圖:我將接受到的packet傳過來后,在構造方法中能夠獲取對應的值(可以看到通過構造方法獲取到的port是55419),但是如果要在run方法中獲取端口號(第三個紅框標記部分)等信息,就獲取不到,程序變成阻塞中,沒有其他報錯信息~

我的代碼如下:
Server:
package?com.socket.socketsender.UDPSoceket;
import?java.io.IOException;
import?java.net.DatagramPacket;
import?java.net.DatagramSocket;
import?java.net.InetAddress;
public?class?UDPServer?{
????public?static?void?main(String[]?args)?throws?IOException?{
????????//接收請求
????????DatagramSocket?socket?=?new?DatagramSocket(8110);//指定服務器端口
????????byte[]?data?=?new?byte[1024];
????????DatagramPacket?packet?=?new?DatagramPacket(data,?data.length);//創建數據報,用于接收客戶端發送的數據
????????System.out.println("========服務器已啟動,正在等待客戶端發送數據======");
????????while?(true)?{
????????????socket.receive(packet);//此方法在接收到客戶端數據之前會一直阻塞
????????????new?Thread(new?ThreadUDPServer(socket,?packet)).start();
????????}
????}
????private?static?class?ThreadUDPServer?implements?Runnable?{
????????private?DatagramPacket?packet;
????????private?String?info;
????????private?DatagramSocket?socket;
????????private?InetAddress?address;
????????private?int?port;
????????public?ThreadUDPServer(DatagramSocket?socket,?DatagramPacket?packet)?{
????????????this.socket?=?socket;
????????????this.packet?=?packet;
????????????this.info?=?new?String(packet.getData(),?0,?packet.getLength());//在run方法中獲取不到info???
????????????this.address=packet.getAddress();
????????????this.port=packet.getPort();
????????}
????????@Override
????????public?void?run()?{
????????????int?test?=?packet.getPort();
????????????System.out.println("接收到客戶端的消息是:"?+?info);
????????????//發送響應信息
????????????byte[]?data2?=?"這是服務器的響應信息:登錄成功".getBytes();
????????????DatagramPacket?packet2?=?new?DatagramPacket(data2,?data2.length,?address,?port);
????????????try?{
????????????????socket.send(packet2);
????????????}?catch?(IOException?e)?{
????????????????e.printStackTrace();
????????????}
????????}
????}
}client:
package?com.socket.socketsender.UDPSoceket;
import?java.io.IOException;
import?java.net.*;
public?class?UDPClient?{
????public?static?void?main(String[]?args)?throws?IOException?{
????????try?(DatagramSocket?socket?=?new?DatagramSocket())?{
????????????//發送請求
????????????InetAddress?addresses?=?InetAddress.getByName("localhost");
????????????byte[]?data?=?"用戶名:小王;密碼:123456".getBytes();
????????????int?port?=?8110;
????????????DatagramPacket?packet?=?new?DatagramPacket(data,?data.length,?addresses,?port);
????????????byte[]?data2?=?new?byte[1024];
????????????socket.send(packet);
????????????//接收響應信息
????????????DatagramPacket?packet2?=?new?DatagramPacket(data2,?0,?data2.length);
????????????socket.receive(packet2);
????????????String?info?=?new?String(data2,0,packet2.getLength());
????????????System.out.println("接收到服務器的響應信息:"+info);
????????}
????}
}
2018-10-14
你的DatagramSocket socket是主線程的東西,新建的其他線程當然用不了,你把sokect放在公共區用volatile修飾讓所有線程共享就可以了,親測。
代碼:
????
public?class?UDPServer2?{ ????public?static?volatile?DatagramSocket?socket;//指定服務器端口 ????static?{ ????????try?{ ????????????socket?=?new?DatagramSocket(8110); ????????}?catch?(SocketException?e)?{ ????????????e.printStackTrace(); ????????} ????} ????public?static?volatile?byte[]?data?=?new?byte[1024]; ????public?static?volatile?DatagramPacket?packet?=?new?DatagramPacket(data,?data.length);//創建數據報,用于接收客戶端發送的數據 ????public?static?void?main(String[]?args)?throws?IOException?{ ????????//接收請求 //????????DatagramSocket?socket?=?new?DatagramSocket(8110);//指定服務器端口 //????????byte[]?data?=?new?byte[1024]; //????????DatagramPacket?packet?=?new?DatagramPacket(data,?data.length);//創建數據報,用于接收客戶端發送的數據 ????????System.out.println("========服務器已啟動,正在等待客戶端發送數據======"); ????????while?(true)?{ ????????????socket.receive(packet);//此方法在接收到客戶端數據之前會一直阻塞 ????????????new?Thread(new?ThreadUDPServer(socket,?packet)).start(); ????????????try?{ ????????????????Thread.sleep(100); ????????????}?catch?(InterruptedException?e)?{ ????????????????e.printStackTrace(); ????????????} ????????} ????} }2018-10-14
還有如要非要用while(true)最好用
解放一下cpu,不然沒很有可能卡機