【问题标题】:Android peer to peer app using Sockets使用 Sockets 的 Android 点对点应用程序
【发布时间】:2014-02-28 14:49:22
【问题描述】:

我希望使用 Sockets 构建一个简单的点对点应用程序。 A 接受一个数字并将其发送给 B。然后 B 将数字的平方返回给 A。

A 在 6000 端口上向 B 发送数据,B 在 8000 端口上向 A 发回数据。因此,两台机器在必须发送时充当客户端,在必须接收时充当服务器。

但是服务器不是应该在客户端之前启动吗?那么,制作这个应用程序的逻辑解决方案是什么?


这是服务器的代码

package com.javacodegeeks.android.androidsocketserver;

.....

public class Server extends Activity {

    private ServerSocket serverSocket;
    private Socket clientSock;

    Handler updateConversationHandler;

    Thread serverThread = null;
    Thread clientThread = null;

    private TextView text;

    public static final int SERVERPORT = 5000;
    public static final int CLIENTPORT = 8000;

    private static final String CLIENT_IP = "10.0.2.2";

    protected IRemote mService;
    private boolean bound = false;
    Intent it;

    private boolean test = false;

    private ServiceConnection mServiceConnection = new ServiceConnection() {

                @Override
                public void onServiceDisconnected(ComponentName name) {
                    // TODO Auto-generated method stub
                    mService = null;
                    Toast.makeText(getApplicationContext(), "no", Toast.LENGTH_SHORT).show();
                    Log.d("IRemote", "Binding - Service disconnected");
                }

                @Override
                public void onServiceConnected(ComponentName name, IBinder service)
                {
                    // TODO Auto-generated method stub
                    mService = IRemote.Stub.asInterface((IBinder) service);
                    Toast.makeText(getApplicationContext(), "yes", Toast.LENGTH_SHORT).show();
                    Log.d("IRemote", "Binding is done - Service connected");
                }
           };

    protected void onDestroy() {

        super.onDestroy();
        unbindService(mServiceConnection);
    };


    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        text = (TextView) findViewById(R.id.text2);

        updateConversationHandler = new Handler();

        this.serverThread = new Thread(new ServerThread());
        this.serverThread.start();

        it = new Intent();
        it.setAction("com.example.mynewclient.RemoteService");

        //it= new Intent(this,IRemote.class);

        //TEMP
        bound = getApplicationContext().bindService(it, mServiceConnection, Context.BIND_AUTO_CREATE);

        Log.d("SERVER", bound ? "Binding is done - Service connected" : "Binding Failed");

        this.clientThread = new Thread(new ClientThread());
        this.clientThread.start();


    }

    @Override
    protected void onStop() {
        super.onStop();
        try {
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void onClick(View view) {
        try {
//          EditText et = findViewById(R.id.text);
            String str = text.getText().toString();//et.getText().toString();
            PrintWriter out = new PrintWriter(new BufferedWriter(
                    new OutputStreamWriter(clientSock.getOutputStream())),
                    true);
            out.println(345+"\n");

            Toast.makeText(getApplicationContext(), "Success", Toast.LENGTH_SHORT).show();

        } catch (UnknownHostException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(), "Exception 1", Toast.LENGTH_LONG).show();               

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(), "Exception 2", Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(), "Exception 3", Toast.LENGTH_LONG).show();
        }
    }


    class ServerThread implements Runnable {

        public void run() {
            Socket socket = null;
            try {
                serverSocket = new ServerSocket(SERVERPORT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            while (!Thread.currentThread().isInterrupted()) {

                try {

                    socket = serverSocket.accept();

                    CommunicationThread commThread = new CommunicationThread(socket);
                    new Thread(commThread).start();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class CommunicationThread implements Runnable {

        private Socket clientSocket;

        private BufferedReader input;

        public CommunicationThread(Socket clientSocket) {

            this.clientSocket = clientSocket;

            try {

                this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void run() {

            BufferedWriter writer;

            while (!Thread.currentThread().isInterrupted()) {

                try {

                    String read = input.readLine();

                    updateConversationHandler.post(new updateUIThread(read));

                    //writer = new BufferedWriter(new OutputStreamWriter(this.clientSocket.getOutputStream()));
                    //writer.write("Server Echos to client");
                    //writer.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    class updateUIThread implements Runnable {
        private String msg;

        public updateUIThread(String str) {
            this.msg = str;
        }

        @Override
        public void run(){

            String message;
            BufferedReader input;

            if(mService == null)
            {
                Log.d("TAG 0", "Inside mservice==null");

                Intent it = new Intent();
                it.setAction("com.example.mynewclient.RemoteService");
                //it.setClassName( "com.example.myclient","com.example.myclient.IRemoteService" );
                //binding to remote service
//              bindService(it, mServiceConnection, Service.BIND_AUTO_CREATE);
            }


            int f = Integer.parseInt(msg);

            try{
                //Toast.makeText(getApplicationContext(), "Result -> Add ->"+mIRemoteService.getSum(3,4), Toast.LENGTH_SHORT).show();
                message = Integer.toString(mService.getSum(f,f));
                text.setText(text.getText().toString()+"The sum is: "+ message + "\n");

            }
            catch(Exception e)
            {
                //setContentView(R.layout.activity_main);
                System.out.println(e.toString());
                Log.e("EXCEPTION 3", e.toString());
                f = f+f;
                message = "Not Successful";

                Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();


            }

        }

        //TEMP Commented
        /*@Override
        public void run() {
            text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
        }*/
    }

    class ClientThread implements Runnable {

        @Override
        public void run() {

            BufferedReader input;

            try {

                Log.d("SERVER", "Client - thread 1");

                InetAddress serverAddr = InetAddress.getByName(CLIENT_IP);

                clientSock = new Socket(serverAddr, SERVERPORT);

                //input = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));

                ///////////////////// 

                Log.d("SERVER", "Client - thread 2");

                //TEMP Commented
                //input = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));

                input = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));

                Log.d("SERVER", "Client - thread 3");

            } catch (UnknownHostException e1) {
                e1.printStackTrace();
                Toast.makeText(getApplicationContext(), "exception 1", Toast.LENGTH_SHORT).show();
            } catch (IOException e1) {
                e1.printStackTrace();
                Toast.makeText(getApplicationContext(), "exception 2", Toast.LENGTH_SHORT).show();
            }

        }

    }

}

这是客户:

package com.javacodegeeks.android.androidsocketclient;
....
public class Client extends Activity {

    private Socket thisSocket;
    private ServerSocket serverSocket;

    private TextView text;

    private static final int SERVERPORT = 6000;
    private static final String SERVER_IP = "10.0.2.2";

    private static final int CLIENTPORT = 8000;

    Handler updateConversationHandler;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     

        new Thread(new ClientThread()).start();

        new Thread(new ServerThread()).start();

    }

    public void onClick(View view) {
        try {
            EditText et = (EditText) findViewById(R.id.EditText01);
            String str = et.getText().toString();
            PrintWriter out = new PrintWriter(new BufferedWriter(
                    new OutputStreamWriter(thisSocket.getOutputStream())),
                    true);
            out.println(str);

        } catch (UnknownHostException e) {
            e.printStackTrace();
            Log.e("SERVER ERROR",e.toString());
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("SERVER ERROR",e.toString());
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("SERVER ERROR",e.toString());
        }
    }

    class ClientThread implements Runnable {

        @Override
        public void run() {

            BufferedReader input;

            try {
                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

                thisSocket = new Socket(serverAddr, SERVERPORT);

                input = new BufferedReader(new InputStreamReader(thisSocket.getInputStream()));

            } catch (UnknownHostException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }

        }

    }

//TEMP  COMMENTED

    class ServerThread implements Runnable {

        public void run() {
            Socket socket = null;
            try {
                serverSocket = new ServerSocket(CLIENTPORT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            while (!Thread.currentThread().isInterrupted()) {

                try {

                    socket = serverSocket.accept();

                    Log.d("CLIENT TAG", "Listening to server");

                    CommunicationThread commThread = new CommunicationThread(socket);
                    new Thread(commThread).start();

                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d("TAG Client 1", "IOException");
                }
                catch (Exception e)
                {
                    Log.d("TAG Client 2", e.toString());
                }
            }
            Toast.makeText(getApplicationContext(), "Client interrupted", Toast.LENGTH_LONG).show();

        }
    }

    class CommunicationThread implements Runnable {

        private Socket clientSocket;

        private BufferedReader input;

        public CommunicationThread(Socket clientSocket) {

            this.clientSocket = clientSocket;

            try {

                this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));

                Log.d("TAG Client 4", "Input from server"+input.toString());

            } catch (IOException e) {
                Log.d("TAG Client 5", "Input from server");
                e.printStackTrace();
            }
            catch (Exception e)
            {
                Log.d("TAG Client 6", "Input from server");
            }
        }

        public void run() {

            BufferedWriter writer;

            while (!Thread.currentThread().isInterrupted()) {

                try {

                    String read = input.readLine();

                    updateConversationHandler.post(new updateUIThread(read));

                    //writer = new BufferedWriter(new OutputStreamWriter(this.clientSocket.getOutputStream()));
                    //writer.write("Server Echos to client");
                    //writer.close();

                    Log.d("TAG Client 7", "Input from server");

                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d("TAG Client 8", e.toString());
                }
            }
        }

    }

    class updateUIThread implements Runnable {
        private String msg;

        public updateUIThread(String str) {
            this.msg = str;
        }

        @Override
        public void run() {
            //text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
            Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
        }
    }



}

【问题讨论】:

  • Abhishek> 你让它工作了吗?
  • 贾斯珀,我最终做到了。差不多 2 年半前,我已经离开了组织和那个项目,这就是为什么我不记得它最终是如何运作的。
  • 谢谢阿布舍克。

标签: android sockets client-server p2p


【解决方案1】:

客户端和服务器之间的区别不在于谁发送或接收数据。在许多情况下,服务器和客户端两者都做。点对点的重点是没有服务器/客户端关系。

话虽如此,您的两个应用程序都应该在您发送任何内容之前运行并开始侦听,除非始终是 A 先发送,在这种情况下您具有客户端/服务器关系。

希望对您有所帮助。

编辑:可能应该提到这一点:您通常使用多个线程进行网络连接,以便在程序的其余部分执行时继续监听至少一个端口。

【讨论】:

  • LeShadow,感谢您的回复。是的,B 确实先发送数字,而 A 将结果发送回(它的正方形)。所以它看起来更像是一个客户端-服务器。在 A 和 B 中,我都创建了一个客户端线程来向对方发​​送数据。为了接收数据,A 和 B 具有通向 UIThread 的线程。我首先启动 A,它能够从 B 接收数字,计算平方并将其发送回来。但 B 没有收到(或没有显示收到)。
  • 理论上你这样做的方式很好。您能否发布有关您的测试环境或代码 sn-ps 的更多详细信息?
  • 好的,我会在大约 18 小时后发布代码,因为我现在不在办公室。
  • 我现在已经添加了代码。注意:getSum 返回数字的平方。所以,基本上我创建了 2 组端口:6000 和 5000 用于客户端到服务器。 8000 & 8000 是从服务器返回到客户端。我还修改了客户端以充当具有侦听器线程和 UI 线程等的服务器。但它没有从服务器获得任何输入。这就是问题所在。
  • 更新:在客户端,在方法 ServerThread(侦听服务器)中,在 serverSocket = new ServerSocket(CLIENTPORT); 行之后我得到 java.net.bindException EADDRINUSE(地址已在使用中)。
【解决方案2】:

每个客户端都应该有一个长连接的Server(比如A,B,C,D.....),A发送msg到Server再转发给D。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 2022-08-21
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    相关资源
    最近更新 更多