我目前正在尝试实现一个应用程序来与一台机器通信,它基本上应该按照以下方式工作:
因此,我们认为有一个线程来执行发送,另一个线程执行接收,因为我们有一个api将一个类注册为从机器接收消息的类(仅通过实现一个接口),并且向机器发送消息的方法不是阻塞类型的,所以需要一种等待机器响应的方法,以便程序能够在响应到达后决定要做什么。
因此,我们需要以某种方式同步这两个线程,因为可以确定它们将交换多少消息,这使我们尝试了一个CyclicBarrier。这是用于测试CyclicBarrier是否会帮助我们解决这个问题的代码(程序实际上并不使用套接字与机器通信,这只是用于测试屏障):
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
public class BlockingTest{
private CyclicBarrier barrier;
class Receiver implements Runnable{
@Override public void run(){
try{
ServerSocket ss = new ServerSocket(8080);
while(!barrier.isBroken()){
System.out.println("Waiting message...");
Socket response = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(
response.getInputStream()));
System.out.printf("Received: %s\n", br.readLine());
barrier.await();
}
}catch(InterruptedException | BrokenBarrierException |
IOException ex){
System.err.println(ex.getMessage());
}
}
}
public BlockingTest(){
this.barrier = new CyclicBarrier(2, new Runnable(){
@Override public void run(){
System.out.println("done.");
}
});
new Thread(new Receiver()).start();
try{
Socket sender = new Socket("localhost", 8080);
PrintWriter pw = new PrintWriter(sender.getOutputStream(), true);
for(int i = 0; i < 3; i++){
System.out.println("Sending message:");
pw.println("Message!");
this.barrier.await();
}
}catch(InterruptedException | BrokenBarrierException | IOException ex){
System.err.println(ex.getMessage());
}
}
public static void main(String[] arg){
new BlockingTest();
}
}如果我们只发送一条消息(在BlockingTest()构造函数中为否块,只需发送消息),则此代码可以正常工作,但是在添加for块之后,它就不能像预期的那样工作了。它只在第一次工作,然后挂起:
Waiting message...
Sending message:
Received: Message!
done.
Waiting message...
Sending message:问题如下:
发布于 2013-10-12 01:06:57
它挂起的原因是,您要打开一个连接到服务器,并继续向它发送数据,但是在接收端,您放弃了第一个连接,并开始等待下一个连接的发生。
您可以在每次发送数据时从发件人创建一个新连接。代码块
Socket sender = new Socket("localhost", 8080);
PrintWriter pw = new PrintWriter(sender.getOutputStream(), true);必须在for循环中移动。(当然,要注意释放所有资源)
或,
将接收器从第一连接中读取数据,而不是等待第二包数据的新连接。
https://stackoverflow.com/questions/19329204
复制相似问题