【问题标题】:Blocking a java socket that is opening/in use阻止正在打开/正在使用的 Java 套接字
【发布时间】:2013-07-07 13:45:13
【问题描述】:

美好的一天,

我在 java 中有一个 sendMessage 函数,看起来像这样。它目前作为一种静态方法存在,可以被任何线程操作(例如 HTTP 请求)调用。但是,如果我要同时发送两个请求..其中一个 sendMessage 请求将引发“连接重置”。

我需要以某种方式知道我当前的端口和 ip 正在使用中!这样我就不会重置连接,而是等待它再次可用。有什么办法吗?

private static String sendMessage(int command,String data,int port,String ip){
    try{
        String sendString=Integer.toString(command)+":"+data+'$'+'\n';
        BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
        Socket clientSocket = new Socket();
        InetAddress addr = InetAddress.getByName(ip);
        SocketAddress sockaddr = new InetSocketAddress(addr, port);
        clientSocket.connect(sockaddr, 20000);

        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        outToServer.writeBytes(sendString);
        String rcvString = inFromServer.readLine();
        System.out.println("FROM DEVICE: " + rcvString);
        clientSocket.close();
        return rcvString;
    }catch(Exception e){
        System.err.println(e.getMessage());
    }

    return NULL;
}

【问题讨论】:

  • 我认为您的客户端代码没有问题。相反,我怀疑您没有为服务器端的每个连接创建线程。
  • 将您的方法synchronized 设为private synchronized static String sendMessage
  • 那会做什么?好的,我正在使用 servlet。所以每个 servlet 请求都根据 jetty doc 在它自己的线程中处理。
  • 那不起作用..它弄乱了我的 TCP 数据

标签: java rest tcp connection


【解决方案1】:

好的,我只是想到了一个巧妙的解决方案,但它很丑。

有一个 blockChecker 类

public class BlockerCheck {

List<String> blockerList;

public BlockerCheck(){
    blockerList=new ArrayList<String>();
}

public synchronized void addBlock(String ip,int port){
    String finalString=ip+":"+Integer.toString(port);
    blockerList.add(finalString);
}

public synchronized void removeBlock(String ip,int port){
    String finalString=ip+":"+Integer.toString(port);
    blockerList.remove(finalString);
}

public synchronized boolean isAvailable(String ip,int port){
    String finalString=ip+":"+Integer.toString(port);
    System.out.println("SIZE:" +blockerList.size());
    return !(blockerList.contains(finalString));
}
}

然后这样使用它:

private static String sendMessage(int command,String data,int port,String ip){
    if(blockerCheck.isAvailable(ip, port)) blockerCheck.addBlock(ip, port);
    else{
        long startTime=TimeUnit.SECONDS.convert(System.nanoTime(), TimeUnit.NANOSECONDS);
        while(!(blockerCheck.isAvailable(ip, port))){
            long currTime=TimeUnit.SECONDS.convert(System.nanoTime(), TimeUnit.NANOSECONDS);
            if((currTime-startTime)>10) return null; //ensure null handled
        }
    }
      //SENDING CODE HERE
      blockerCheck.removeBlock(ip, port);
}

【讨论】:

  • 我想要一些意见。我需要包含 sendMessage 的同步标签吗?
猜你喜欢
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-22
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
相关资源
最近更新 更多