关于线程通信DatagramPacket的求助

先放代码
问题出现在服务器端的计算线程
客户机的计算式格式为:+9 6//代表9+6

package homework2;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.ReentrantLock;
import java.io.IOException;
import java.net.*;


public class UDPserver {
	public static void main(String args[]){
		DatagramSocket aSocketin=null;
		DatagramSocket aSocketout=null;
		try {
			aSocketin = new DatagramSocket(8080);
			aSocketout = new DatagramSocket(8081);
			BlockingQueue<DatagramPacket> in = new LinkedBlockingQueue<DatagramPacket>(10);
			BlockingQueue<DatagramPacket> out = new LinkedBlockingQueue<DatagramPacket>(10);		
			ReceiveThread inrun = new ReceiveThread(in, aSocketin);
			SendThread outrun = new SendThread(out, aSocketout);
			new Thread(inrun).start();
			
			CalculateThread_Recycle caculate = new CalculateThread_Recycle(in, out);
			new Thread(caculate).start();
			new Thread(outrun).start();
		}catch (SocketException e) {
			System.out.println("Socket: " + e.getMessage());
		}
	}
}

//接收线程
class ReceiveThread implements Runnable{
	DatagramSocket aSocket=null;
	byte[] buffer = new byte[1000];
	DatagramPacket temp = new DatagramPacket(buffer, buffer.length);
	private BlockingQueue<DatagramPacket> in;
	public ReceiveThread(BlockingQueue<DatagramPacket> in, DatagramSocket socket){
		this.in = in;
		this.aSocket = socket;
	}
	public void run(){
		System.out.println("received start");
		while (true) {
				try {
					aSocket.receive(temp);
					in.put(temp);
					System.out.println("received succeed"+new String(temp.getData()));
				} catch (IOException | InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}			
		}
	}
}

//发送线程
class SendThread implements Runnable{
	private DatagramSocket sendSocket;
	private BlockingQueue<DatagramPacket> out;
	public SendThread ( BlockingQueue<DatagramPacket> out,DatagramSocket socket) {
		this.sendSocket = socket;
		this.out = out;
	}
	public void run() {
		System.out.println("Send start");
			while(true) {
				try {
					Thread.sleep(300);
					DatagramPacket dd = out.take();
					sendSocket.send(dd);
					System.out.println("Send finish"+new String(dd.getData()));
				} catch (InterruptedException | IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				}								
			}
		}
	}


//计算线程
class CalculateThread_Recycle implements Runnable{
	private BlockingQueue<DatagramPacket> in, out;
	private static int[] operationCounter = new int[4];
	public CalculateThread_Recycle(	BlockingQueue<DatagramPacket> in,BlockingQueue<DatagramPacket> out) {
		this.in = in;
		this.out = out;
	}
	public void run (){
		try{
			while (true) 
			{
				Thread.sleep(300);
				DatagramPacket p = in.take();
				DatagramPacket result=null;
				String str = new String(p.getData()).trim();
				System.out.println(str);
				char x = str.charAt(0);
				int a,b,j = 0;
				int firstIndex = str.indexOf(' ');
				a = Integer.parseInt(str.substring(1, firstIndex));
				b = Integer.parseInt(str.substring(firstIndex+1,str.length()));
				if(x=='+') {
					j=a+b;
					operationCounter[0]++;
					System.out.println(a+"+"+b+"="+j+"加法运算共:"+operationCounter[0]+"次");
					str=String.valueOf(j);
				}else if(x=='-') {
					j=a-b;
					operationCounter[1]++;
					System.out.println(a+"-"+b+"="+j+"减法运算共:"+operationCounter[1]+"次");
					str=String.valueOf(j);
				}else if(x=='*') {
					j=a*b;
					operationCounter[2]++;
					System.out.println(a+"*"+b+"="+j+"乘法运算共:"+operationCounter[2]+"次");
					str=String.valueOf(j);
				}else if(x=='/') {
					j=a/b;
					operationCounter[3]++;
					System.out.println(a+"/"+b+"="+j+"除法运算共:"+operationCounter[3]+"次");
					str=String.valueOf(j);
				}else {
					str=new String("Input error,please try angin");
				}
				byte[] ss = str.getBytes();
				System.out.println("offer"+str);		
				result=new DatagramPacket(ss, ss.length,p.getAddress(),p.getPort());//在这里发生里阻塞
				System.out.println("offer"+str);
				while(out.offer(result)==false) {
						Thread.sleep(200);
						System.out.println("offer1"+str);
				}
				System.out.println("putok"+ss.toString());
			}
		}catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
```下面展示一些 `内联代码片`。

在这里发生了阻塞


```javascript
				System.out.println("offer"+str);		
				result=new DatagramPacket(ss, ss.length,p.getAddress(),p.getPort());//在new DatagramPacket的时候发生了阻塞
				System.out.println("offer"+str);

输出结果
如果客户机再次输入一个计算式则会返回上一个计算的结果
但是这次的计算式不被计算,第三次输入计算式结果又和第一次的类似,在new DatagramPacket的时候阻塞。
红圈为每次输入的结果,每次输入我是手动的有很多空余时间用来运算。
在这里插入图片描述
如果我创建多个计算线程那么则会导致每次客户机的接受结果为上一次计算式的答案
在这里插入图片描述
我很好奇为什么,求求大佬解答

补充一下客户端的代码,虽然我觉得这里没有问题

// An highlighted block
var foo = 'bar';
```package homework2;
import java.net.*;
import java.util.Scanner;
import java.io.*;

public class UDPClient{
	public static void main(String args[]){
		DatagramSocket aSocket = null;
		int serverPort = 8080;
		byte[] buffer = new byte[1000];
		DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
		while(true) {
			try {
				aSocket = new DatagramSocket();
				Scanner s = new Scanner(System.in);
				byte[] m = s.nextLine().getBytes();
				InetAddress aHost = InetAddress.getByName("127.0.0.1");
				DatagramPacket request = new DatagramPacket(m, m.length, aHost, serverPort);
				aSocket.send(request);
				
				aSocket.receive(reply);
				System.out.println("Reply: " + new String(reply.getData()));
			} catch (SocketException e){
				System.out.println("Socket: " + e.getMessage());
			} catch (IOException e){
				System.out.println("IO: " + e.getMessage());
			} finally { 
				if(aSocket != null) aSocket.close();
			}
		}
		
	}
}
发布了1 篇原创文章 · 获赞 0 · 访问量 284

猜你喜欢

转载自blog.csdn.net/zzjjyyeom/article/details/104802436