【问题标题】:Java code for getting the status of multiple IP,Port using socket connection使用socket连接获取多个IP、端口状态的Java代码
【发布时间】:2013-12-15 13:50:19
【问题描述】:

我开发了一个代码,用于使用套接字返回主机列表状态的多个主机和端口连接。问题是 ping 并返回仅 10 个连接的状态需要 5 分钟。任何想法为什么需要这么长时间?

import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.PortUnreachableException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestIPList {
    private static final Logger logger = LoggerFactory.getLogger(TestIPList.class);
    static ArrayList<String> ipList = new ArrayList<String>();
    public static ArrayList<String> captureValues() throws IOException,ConnectException
    {           
        //Pattern ptn = Pattern.compile("(\\d{1,3})\\.(\\d{1,3})\\.
                                                (\\d{1,3})\\.(\\d{1,3})");
        Scanner ipFile    =  null;
        String iList="";
        ArrayList<String> ips = new ArrayList<String>();
        ArrayList<String> returnList = new ArrayList<String>();
            /*read the file at local path */
        try {
            ipFile = new Scanner (new File ("c:\\list.txt"));
        }
        catch(IOException e){
            logger.debug( "[-] Cant open the file!");
            System.exit(0);
        }
            /*Iterate thru the file */
        while(ipFile.hasNext()){
            ips.add(ipFile.next());
        }
        String[] ipPort;
        for(int i=0;i<ips.size();i++){
            iList = ips.get(i);
            ipPort= iList.split(":");
            Socket ss = null;
            boolean status = false;
            try {
                            /*Socket class.. here it is taking time to ping*/
                ss = new Socket(ipPort[0], Integer.parseInt(ipPort[1]));
                status = true; //there is a listening port 
                ss.close();
            }
            catch (IOException e) {
                //e.printStackTrace();
            } 
            finally {
                if (ss != null) {
                    try {
                        ss.close();
                    }
                    catch(PortUnreachableException e)
                    {
                        ss=null;
                        System.err.println("Got an "+e);
                    }
                    catch (UnknownHostException e) {  
                        // TODO Auto-generated catch block  
                        ss=null;
                        System.err.println("Got an "+e);  
                    }
                    catch (IOException e) {
                        ss=null;
                    }
                }
            }
                    /*return status*/
            if(status==true){
                returnList.add("true");
            }
            else{ 
                returnList.add("false");
            }

        }
            /* return list of status*/
        return returnList;
    }
            /*static method*/
    public static void main(String a[]) throws IOException,ConnectException {
        /* Into the main method */
            ArrayList<String> ipexists = new ArrayList<String>();
        ipexists =captureValues();
        System.out.println("ArrayList Status---------"+captureValues());
           /*End of the program*/
    }

}

【问题讨论】:

    标签: java sockets ip port


    【解决方案1】:

    您可能想尝试指定超时:

    SocketAddress sa = new InetSocketAddress(ipPort[0], Integer.parseInt(ipPort[1]));
    Socket ss = new Socket();
    int timeoutMillis = 500;
    ss.connect(sa, timeoutMillis);
    

    编辑:为了对多个线程执行相同的操作,您可以像这样修改代码:

    final ArrayList<String> ips = new ArrayList<String>();
    // ..
    final List<String> returnList = Collections.synchronizedList(new ArrayList<String>(ips));
    Collections.fill(returnList, "false");
    
    int nThreads = 10;
    final ExecutorService es = Executors.newFixedThreadPool(nThreads);
    for (int i = 0; i < ips.size(); i++) {
        final int index = i; // needs to be final to be available in local class
        es.execute(new Runnable() {
            @Override
            public void run() {
                String iList = ips.get(index);
                String[] ipPort = iList.split(":");
                final String host = ipPort[0];
                final int port = Integer.parseInt(ipPort[1]);
                Socket ss = null;
                boolean status = false;
                try {
                    int timeoutMillis = 1500;
                    InetAddress ia = InetAddress.getByName(host);
                    // Edit: isReachable often fails for public sites
                    //if (!ia.isReachable(timeoutMillis))
                    //  throw new UnknownHostException(host);
                    SocketAddress sa = new InetSocketAddress(ia, port);
                    ss = new Socket();
                    ss.connect(sa, timeoutMillis);
                    status = true;
                    ss.close();
                } catch (IOException e) {
                    // e.printStackTrace();
                } finally {
                    if (ss != null) {
                        try {
                            ss.close();
                        } catch (PortUnreachableException e) {
                            ss = null;
                            System.err.println("Got an " + e);
                        } catch (UnknownHostException e) {
                            // TODO Auto-generated catch block
                            ss = null;
                            System.err.println("Got an " + e);
                        } catch (IOException e) {
                            ss = null;
                        }
                    }
                }
                /* return status */
                if (status == true) {
                    returnList.set(index, "true");
                } else {
                    returnList.set(index, "false");
                }
            }
        });
    }
    es.shutdown();
    es.awaitTermination(60, TimeUnit.SECONDS);
    List<Runnable> pending = es.shutdownNow();
    if (!pending.isEmpty()) System.err.println("Pending threads: " + pending);
    

    对于另一个多线程、更复杂的示例,您可能需要查看 Oracles NIO and NIO.2 Examples 的 Ping.java。


    编辑:注释掉 isReachable 分支,因为它很少适用于公共网站。

    【讨论】:

    • 非常感谢兄弟..它现在可以工作了。另外,如果有人可以建议如何使用线程进行有效的轮询。
    • 感谢您的回复,但是这个多线程代码不起作用..你测试了吗?它给出以下错误:线程“pool-1-thread-8”中的异常线程“pool-1-thread-7”中的异常java.lang.IndexOutOfBoundsException:索引:7,大小:0java.lang.IndexOutOfBoundsException:索引: 6、大小:0 at java.util.ArrayList.set(ArrayList.java:638) at java.util.ArrayList.set(ArrayList.java:638) at java.util.Collections$SynchronizedList.set(Collections.java: 664)at ERROR Occuring at line :/* return status */ if (status == true) {returnList.set(index, "true");
    • 您是否根据我的代码将returnList 的初始化修改为Collections.synchronizedList(new ArrayList&lt;String&gt;(ips));(必须在 ips 初始化之后进行)?它保证returnListips 具有相同的大小。我刚刚用final List&lt;String&gt; ips = Arrays.asList("www.google.com:443", "www.yahoo.fi:80", "www.suse.de:80", "www.ub.edu:80"); 重新测试了它,发现isReachable 分支很少适用于公共站点。我将对其进行编辑。
    • 你当然感谢,如果可以的话,请在此处粘贴完整的程序,它工作正常。
    • 嗨...您能否尝试将这些主机:端口值放入文本文件并从中读取。如果我们这样做,它会给出 arrayindexoutofbound 异常
    猜你喜欢
    • 2019-04-10
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 2016-11-06
    • 2013-05-07
    • 1970-01-01
    相关资源
    最近更新 更多