为了账号安全,请及时绑定邮箱和手机立即绑定

关于udp使用多线程实现多客户端请问人写出来吗?按照之前的tcp那种写法不成功啊

如题,因为packet传到线程里后不起作用啊,测了下,不为空,但它的方法都用不了啊,有谁知道吗。老师没讲这个网上查到的资料也很有显。幕课之前也有人问同样的问题,但并没有回答

正在回答

7 回答

public class UDPServerThread extends Thread {
	DatagramSocket socket = null;
	DatagramPacket packet = null;
	public UDPServerThread(DatagramPacket packet,DatagramSocket socket){
		this.packet = packet;
		this.socket = socket;
	}
	public void run(){
		byte[] data = packet.getData();
		String info = new String(data,0,packet.getLength());
		System.out.println("我是服务器,客户端说:"+info);
		//响应客户端
		InetAddress address = packet.getAddress();
		int port = packet.getPort();
		byte[] data2 = "欢迎您!".getBytes();
		DatagramPacket packet2 = new DatagramPacket(data2, data2.length,address, port);
		try {
			socket.send(packet2);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
/*
 * 服务器端,实现基于UDP的用户登陆
 */
public class UDPServer {

	public static void main(String[] args) throws IOException {
		//创建服务器端DatagramSocket,指定端口号
		DatagramSocket socket = new DatagramSocket(8800);
		byte[] data = new byte[1024];//创建字节数组,指定接收的数据报的大小
		int count=0;
		System.out.println("*******服务器端已经启动,等待客户端发送数据**********");
		while(true){
			DatagramPacket packet = new DatagramPacket(data, data.length);
			socket.receive(packet);
			UDPServerThread serverThread = new UDPServerThread(packet, socket);
			serverThread.start();
			count++;
			System.out.println("客户端的数量是"+count);
		}
	}
}


1 回复 有任何疑惑可以回复我~
#1

moluchase

问你一下,为什么要把DatagramPacket packet = new DatagramPacket(data, data.length);这句写到while里面啊? 我写到外面的时候,第一个客户端一直不出结果,后面几个客户端却正常,找来找去只能发现是packet不能在Thread中使用,却不知道什么原因
2016-08-06 回复 有任何疑惑可以回复我~
#2

moluchase 回复 moluchase

懂了,packet被占据了,用了serverThread.join();就好了
2016-08-06 回复 有任何疑惑可以回复我~
#3

Airly 回复 moluchase

为什么不是把DatagramPacket 放while里呢?难道不是为每个客户端创建一个数据报?放到while里面就是当每次有数据时就创建一个新的数据报啊......能不能说说你的思路?
2016-10-25 回复 有任何疑惑可以回复我~
#4

Mad_Man_ 回复 moluchase

什么意思 啊 我现在也遇到这个问题了
2017-07-26 回复 有任何疑惑可以回复我~
#5

MEI有头绪 回复 Airly

数据报如果为单例的,岂不是数据会累加?
2019-01-05 回复 有任何疑惑可以回复我~
#6

MEI有头绪 回复 Mad_Man_

因为放在外边的时候,采用start()方法,packet类在run()方法中在运行,因为start()方法本身不用等待run()方法执行完毕,继续执行后边的代码,所以容易导致下次执行要用packet的时候,上一次还在run()里面执行,导致占用,如果采用join(),会等待此线程执行完,在执行join()之后的代码,所以就可以了。
2019-01-05 回复 有任何疑惑可以回复我~
查看3条回复


仅供参考:

public class UdpSocketMilServerDemo {

public static void main(String[] args) {

DatagramSocket socket = null;

try {

/*

* 接受客户端发送到服务器的数据信息

*/

int count = 0;

//创建DatagramSocket,指定端口

socket = new DatagramSocket(8800);

while(true){

//创建DatagramPacket,用于存储客户端发送的信息

byte[] data = new byte[1024];

DatagramPacket packet = new DatagramPacket(data, data.length);

//接受从客户端发送来的请求信息,并存储在DatagramPacket中

socket.receive(packet);

UdpThread thread = new UdpThread(socket, data, packet);

thread.start();

count++;

System.out.println("总共有"+count+"个用户登录");

}

} catch (SocketException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}finally{

socket.close();

}

}

}

public class UdpThread extends Thread {

private DatagramSocket socket;

private byte[] data;

private DatagramPacket packet;

public UdpThread(DatagramSocket socket,byte[] data,DatagramPacket packet){

this.socket = socket;

this.data = data;

this.packet = packet;

}


@Override

public void run() {

try {

//读取获取到的客户信息

String info = new String(data, 0, packet.getLength());

System.out.println("我是服务端,客户端说:"+info);

/* 

 * 对客户端的请求进行响应

 */

 

//获取客户端主机信息和定义要响应的信息

InetAddress address = packet.getAddress();

int port = packet.getPort();

byte[] data2 = "欢迎您!".getBytes();

//定义一个DatagramPaket,用户存放响应信息

DatagramPacket responsePacket = new DatagramPacket(data2, data2.length, address, port);

//发送响应信息

socket.send(responsePacket);

} catch (IOException e) {

e.printStackTrace();

}

}

}


3 回复 有任何疑惑可以回复我~
#1

SilenceDean

谢谢了
2016-07-25 回复 有任何疑惑可以回复我~
#2

SilenceDean

有个疑问,在while(true)里面放byte data=new byte[1024]; 是每次执行都是将data内容清空并重新开辟内存空间,相当于重新赋值么?
2016-07-25 回复 有任何疑惑可以回复我~
#3

Airly 回复 SilenceDean

并不是重新赋值而是重新创建了一个这个对象。
2016-10-25 回复 有任何疑惑可以回复我~
#4

Airly 回复 Airly

因为要为每一个客户端对象创建一个实例....
2016-10-25 回复 有任何疑惑可以回复我~
查看1条回复

我的也不行,运行不出来。有没有源代码参考一下

0 回复 有任何疑惑可以回复我~

可以发一下源代码参考一下?

0 回复 有任何疑惑可以回复我~

感觉因为现在人数多了还是怎么的,幕课网现在都已经没老师来回答问题了,以前的时候人发问题总有。唉,现在就只剩些学生互相猜解了。

0 回复 有任何疑惑可以回复我~
#1

慕粉1651148

同感。前面的一些课程老师的回答明显看得出来要多些
2016-04-14 回复 有任何疑惑可以回复我~

额,我已经找到答案了,udp的datagrampacket接受数据只能用一个线程接收。所以要先接受后将数据提交线程池处理即可

0 回复 有任何疑惑可以回复我~
#1

慕粉1651148

能不能说清楚点,毕竟我还是菜鸡
2016-04-14 回复 有任何疑惑可以回复我~
#2

狮子追求真理 提问者 回复 慕粉1651148

例如socket.receive(packet)后将packet得到的数据也就是字节数组传给新线程处理。而不是直接传packet。
2016-04-14 回复 有任何疑惑可以回复我~
#3

慕粉1651148

刚刚我自己搞好了, 花了不少时间啊
2016-04-14 回复 有任何疑惑可以回复我~
#4

慕兰雪下 回复 狮子追求真理 提问者

请问为什么不能直接传packet呢?
2016-04-26 回复 有任何疑惑可以回复我~
#5

慕兰雪下 回复 狮子追求真理 提问者

请问为什么不能直接传packet呢?
2016-04-26 回复 有任何疑惑可以回复我~
#6

Airly 回复 狮子追求真理 提问者

同问,为什么不能直接传packet呢?我直接传packet并没有什么问题啊,还是正常运行的。
2016-10-25 回复 有任何疑惑可以回复我~
查看3条回复

同问!

0 回复 有任何疑惑可以回复我~
#1

水止三千

把packet传入线程可以用的,
2016-07-22 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

关于udp使用多线程实现多客户端请问人写出来吗?按照之前的tcp那种写法不成功啊

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信