在Android/Java中设置S/C之间的TCP连接

在Android/Java中设置S/C之间的TCP连接,android,tcp,multicast,Android,Tcp,Multicast,我正在设计一个全对全Android程序,包括5个节点: 每个节点同时充当服务器和客户端 每个节点将连接到其他4个节点 每个节点将侦听并接受其他4个节点的连接 但我的问题是,如果5个节点按:1-2-3-4-5的顺序启动,Node1的tcp连接请求将不会被Node2接受,因为Node2在1之后启动 为了解决这个问题,我尝试使用isConnected(),但它总是返回true,即使只有Node1启动 所以我的问题是如何在3个Android节点之间建立一个全对全TCP连接 附件是我的代码: privat

我正在设计一个全对全Android程序,包括5个节点:

  • 每个节点同时充当服务器和客户端
  • 每个节点将连接到其他4个节点
  • 每个节点将侦听并接受其他4个节点的连接
  • 但我的问题是,如果5个节点按:1-2-3-4-5的顺序启动,Node1的tcp连接请求将不会被Node2接受,因为Node2在1之后启动

    为了解决这个问题,我尝试使用
    isConnected()
    ,但它总是返回
    true
    ,即使只有Node1启动

    所以我的问题是如何在3个Android节点之间建立一个全对全TCP连接

    附件是我的代码:

    private class ClientTask extends Thread {
            Socket[] s1 = new Socket[5];
    
            @Override
            public void run() {
                int flag=1;
                for (int i = 0; i < 5; i++) {
                    if(flag==0) i--;
                    try {
                        System.out.println("Begin making connections!");
                        //s1[i] = new Socket(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),REMOTE_PORT[i]);
                        s1[i] = new Socket();
                        s1[i].connect(new InetSocketAddress("10.0.2.2", REMOTE_PORT[i]),1000);
                        flag=1;
                    } catch (UnknownHostException e) {
                        System.out.println("ClientTask UnknownHostException");
                        flag=0;
                    } catch (IOException e) {
                        //Error happens when set_redir.py is not run
                        System.out.println("ClientTask socket IOException");
                        flag=0;
                    }
                }
            }
        }
    
    private类ClientTask扩展线程{
    套接字[]s1=新套接字[5];
    @凌驾
    公开募捐{
    int标志=1;
    对于(int i=0;i<5;i++){
    如果(标志==0)i--;
    试一试{
    System.out.println(“开始建立连接!”);
    //s1[i]=新套接字(InetAddress.getByAddress(新字节[]{10,0,2,2}),远程_端口[i]);
    s1[i]=新套接字();
    s1[i].connect(新的InetSocketAddress(“10.0.2.2”,远程_端口[i]),1000);
    flag=1;
    }捕获(未知后异常e){
    System.out.println(“ClientTaskUnknownHostException”);
    flag=0;
    }捕获(IOE异常){
    //未运行set_redir.py时发生错误
    System.out.println(“ClientTask套接字IOException”);
    flag=0;
    }
    }
    }
    }
    
    以及服务器的代码:

    public class ServerTask extends Thread {
            ServerSocket serverSocket = null;
    
            public void run() {
                System.out.println("Start listening!");
                Socket socket = null;
                try {
                    serverSocket = new ServerSocket(10000);
                } catch (IOException e) {
                    System.out.println("Error when creating serversocket!");
                }
                int flag=1;
                for (int i = 0; i < 5; i++) {
                    if(flag==0) i--;
                    try {
                        // waiting for incoming socket
                        socket = serverSocket.accept();
                        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                        try{
                            out.writeBytes("You are connected to avd: " + (myPort-11108)/4);
                        }catch (IOException e){
                            System.out.println("Error here!");
                        }
                        flag=1;
                        // new thread for the full TCP connection
                        System.out.println("Receiving new TCP connection from " + socket.getRemoteSocketAddress());
                        tt[i] = new tcpThread(socket, i);
                        tt[i].start();
                    } catch (IOException e) {
                        System.out.println("ERROR: server socket");
                        flag=0;
                    }
                }
                System.out.println("End listening...");
            }
        }
    
    public类ServerTask扩展线程{
    ServerSocket ServerSocket=null;
    公开募捐{
    System.out.println(“开始监听!”);
    套接字=空;
    试一试{
    serverSocket=新的serverSocket(10000);
    }捕获(IOE异常){
    System.out.println(“创建serversocket时出错!”);
    }
    int标志=1;
    对于(int i=0;i<5;i++){
    如果(标志==0)i--;
    试一试{
    //等待传入套接字
    socket=serverSocket.accept();
    DataOutputStream out=新的DataOutputStream(socket.getOutputStream());
    试一试{
    out.writeBytes(“您已连接到avd:”+(myPort-11108)/4);
    }捕获(IOE异常){
    System.out.println(“此处出错!”);
    }
    flag=1;
    //完整TCP连接的新线程
    System.out.println(“从“+socket.getRemoteSocketAddress()”接收新的TCP连接);
    tt[i]=新的tcpThread(socket,i);
    tt[i].start();
    }捕获(IOE异常){
    System.out.println(“错误:服务器套接字”);
    flag=0;
    }
    }
    System.out.println(“结束侦听…”);
    }
    }
    
    在Stackoverflow和google做了一些研究之后,我找到了检测服务器是否在线或离线的方法。我正在写以下笔记,以防将来有人面临同样的问题:>

    无论服务器是否在线,我们都可以使用
    read()
    readLine()
    ,而不是使用
    isConnected()
    ,只要连接确实是由客户端发出的,这将始终是
    true

    read()
    将返回
    -1
    ,如果由于连接丢失、服务器关闭等原因未实际设置连接

    readLine()
    将一直计时,与上述情况相同


    因此,我们可以检查返回值是
    -1
    还是超时
    readLine()
    ,以检查TCP连接的状态。

    什么是“S/C”?短路?@EJP服务器/客户端…为什么不这么说?一切都不是TLA。可能什么都有,到处都是错误。如果
    read()
    返回-1,
    readLine()
    将在相同的情况下返回
    null
    ,而不是永远阻塞
    isConnected()
    在连接或接受套接字后永远返回true。它是套接字的属性,而不是连接的属性。如果连接丢失,则说明
    read()
    将返回-1是不正确的。可靠地检测的唯一方法是发送。如果您能区分服务器不活动和响应失败,读取超时可能会有所帮助。@EJP Thx供您评论!我正在做一个项目,面临不少TCP问题。从
    read()
    返回值的文档中,
    数据的下一个字节,或者-1(如果到达流的结尾)。
    。那么为什么我们不能说如果连接丢失,
    read()将返回-1呢。
    ?因为它可能会永远阻塞
    read()
    不会发出任何网络协议,因此它只会等待某些事情发生,而在死掉的连接上发生某些事情的唯一方法是尝试向其发送。