Android WiFi Direct客户端套接字超时

时间:2017-01-30 04:59:00

标签: android sockets

我是Android的新手,对套接字编程有些新意。我有两个设备,运行Android 5.1,直接与WiFi连接(不确定是否相关)。我有一个服务,服务器在套接字上侦听请求,然后将回复返回给客户端。

同样,客户端代码发送请求并侦听来自服务器的回复。服务器正在发送响应,但客户端永远不会收到消息,并且套接字超时。

服务器测试代码:

while (true) {
    try {
        Log.i(TAG, "test waiting for a request");
        mServer = new ServerSocket(PORT);
        Socket socket = mServer.accept(); //Block to receive message //
        BufferedReader in = new BufferedReader(new  InputStreamReader(socket.getInputStream()));
        Log.i(TAG, "Message received! " + in.readLine());

        String msg = "This is my reply.";
        OutputStream outputStream = socket.getOutputStream();
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
        out.println(msg);
        out.flush();
        out.close();

    } catch (SocketException e) {
        Log.e(TAG, "Socket Accept Interrupted", e);
    } catch (IOException e) {
        Log.e(TAG, "Socket Failure", e);
    } finally {
        if (mServer != null && mServer.isBound()) {
            try {
                mServer.close();
            } catch (IOException ioException) {
                Log.e(TAG, "Failed to close socket trying to recover from SocketException", ioException);
            }
        }
    }
}

客户端测试代码:

    Socket socket = null;
    SocketAddress addr = new InetSocketAddress(host, PORT);
    int socketTOms = 5000;
    try  {
        socket = new Socket(host, PORT);
        socket.setKeepAlive(false);
        String syncReq = "Request to server.";

        //Send Request//
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(syncReq.getBytes());
        socket.setSoTimeout(socketTOms);

        //Rcv reply//
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        Log.i(TAG, "Message received! " + in.readLine());

    } catch (SocketTimeoutException e) {
        Log.e(TAG, "Timeout while reading from socket: timeout=" + socketTOms);
    } catch (Exception e) {
        Log.e(TAG, "Exception", e);
    } finally {
        if (socket != null && socket.isConnected()) {
            try {
                socket.close();
            } catch (IOException e) {
                Log.e(TAG, "Exception while closing socket", e);
            }
        }
    }

我通过Android Studio在两个不同的设备上运行服务器和客户端,并且可以在日志中看到服务器收到请求并发送回复,但客户端总是throws {{1} }。我看到SocketTimeoutException可以解决问题的其他地方,但它似乎没有任何影响。

看起来很简单,但我无法看到我在这里失踪的东西。

2 个答案:

答案 0 :(得分:0)

可以在无限循环mServer = new ServerSocket(PORT);

之前尝试这行代码

您是否尝试在服务器端应用中创建线程?这使得进程并行运行,以便在服务器等待请求时,应用程序不会挂起。首先尝试使用localhost的代码。要查找Inetaddress,只需使用InetAddress.getLocalHost()。然后运行它。对于与不同设备的通信,提供称为(NSD)(网络服务Discovary)的服务。

但是如果你想以这种方式运行,我已经为你编写了代码。

服务器端代码

 TextView textView;
    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView=(TextView)findViewById(R.id.textView);
        button=(Button)findViewById(R.id.button);

button.setOnClickListener(
        new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                connect();
            }
        }
);



    }


    public void connect()
    {

        MyServer myServer= new MyServer();
        myServer.setEventListener(this);
        myServer.startListening();

    }





    @Override
    public void Display(String message) {

        textView.setText("Client - "+ message);
    }
}

客户端代码

 TextView textView;
    Button button;
    Thread mThread;
    Socket clientSocket;
Button sendBtn;
  public  String userText1;
    ObjectOutputStream output;
    EditText editText;
    Object userText;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView=(TextView)findViewById(R.id.textView);
        button=(Button)findViewById(R.id.button);
        sendBtn=(Button)findViewById(R.id.sendBtn);
       editText=(EditText)findViewById(R.id.editText);
        sendBtn.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        userText=editText.getText().toString();


                       start();
                    }
                }
        );




    public void start()
    {
       mThread= new Thread(new Runnable() {
           @Override
           public void run() {

               try {
                   clientSocket = new Socket("127.0.0.1", 2001);
                   Log.v("binaya", "client socket created");
                   output = new ObjectOutputStream(clientSocket.getOutputStream());
                   output.writeObject(userText);
                   Message serverObj = Message.obtain();
                   ObjectInputStream input = new ObjectInputStream(clientSocket.getInputStream());


                   String strMsg = input.readObject().toString();
                   serverObj.obj = strMsg;

                   mHandler.sendMessage(serverObj);

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


           }
       });
    mThread.start();
    }


     Handler mHandler= new Handler()
     {
         @Override
         public void handleMessage(Message msg) {
             msgDisplay(msg.obj.toString());
         }
     };

    private void msgDisplay(String msg) {
    textView.setText("Server - " +  msg);

    }

我们使用过处理程序,因为在这种情况下我们无法从runnable内部触摸用户界面。 感谢

答案 1 :(得分:0)

想出来...... 在客户端,我使用outputStream.write(...)将请求发送到服务器,如下所示:

    String syncReq = "Request to server.";
    OutputStream outputStream = socket.getOutputStream();
    outputStream.write(syncReq.getBytes());

但是使用BufferedReader.readLine()在服务器上阅读:

    Socket socket = mServer.accept(); //Block to receive message //
    BufferedReader in = new BufferedReader(new  InputStreamReader(socket.getInputStream()));
    Log.i(TAG, "Message received! " + in.readLine());

我的问题是outputStream.write(...)在字符串的末尾没有附加'\ n',但服务器上的in.readLine()需要它。因此服务器在等待'\ n'时阻塞;这反过来导致客户端套接字超时。