首页 文章

Android WiFi Direct客户端套接字超时

提问于
浏览
1

我是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 SocketTimeoutException . 我在其他地方看到 socket.setKeepAlive(false) 会解决问题,但似乎没有任何影响 .

看起来很简单,但我看不到我在这里缺少的东西 .

2 回答

  • 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内部触摸用户界面 . 谢谢

  • 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'时阻塞;这反过来导致客户端套接字超时 .

相关问题