Android套接字连接但无法写入

时间:2014-09-26 22:38:41

标签: java android sockets networking

我试图在我的应用程序中进行一些网络连接,但我遇到了一些问题。似乎我无法写入OutputStream对象。虽然我的服务器收到连接,但它没有收到任何数据。我尝试过使用Writer,DataOutputStream等。似乎没有人工作。 我的应用程序使用asynctasks,使用Socket对象和消息调用此对象。 (使用setStreams方法初始化后,套接字对象已用于设置Streams。) 有人可以试着找到问题吗?我将非常感激。

public class NetworkingUtils {
private OutputStream out = null;
private InputStream in = null;

//set streams
public void setStreams(Socket sock){
    if (sock.isConnected()) {
        try {
            this.out = (OutputStream) sock.getOutputStream();
            this.in = (InputStream) sock.getInputStream();
        } catch (Throwable e) {
            Log.d("SOCKET", "FAILED TO SET STREAMS");
            e.printStackTrace();
        }
    }
}

//send \n terminated messages to pre defined socket
public void sendMessage(Socket sock, String message) throws Throwable {
    if (sock.isConnected()) {
        try {
            this.out.write(message.getBytes());
            Log.d("SOCKET","WRITING COMPLETE. " + message);
        } catch (Throwable e) {
            throw e;
        }
    }
}

public String recvMessage(Socket sock) throws Throwable {
    //receives \n terminated message from pre defined socket
    String answer = null;
    if (sock.isConnected()){
        try{
            answer = this.convertStreamToString(this.in);
            Log.d("SOCKET","READING COMPLETE");
        }
        catch (Throwable e){
            Log.d("socket",e.getLocalizedMessage());
            throw e;
        }
    }
    else{
        Log.d("socket","is not connected!!!");
    }
    if (answer.length() == 0){
        //empty string answer from server
        throw new IOException();
    }
    else {
        return answer;
    }

}

private String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = null;
    try{
     s = new java.util.Scanner(is).useDelimiter("\r\n");}
    catch (Throwable e){
        e.printStackTrace();
    }
    return s.hasNext() ? s.next() : "";
}

}

2 个答案:

答案 0 :(得分:3)

我只能看到一个客户端可能导致这个......我对此表示怀疑。 (也就是说:试试这个,以防它产生差异,但我认为不会。)

  this.out.write(message.getBytes());
  Log.d("SOCKET","WRITING COMPLETE. " + message);

潜在的问题是如果out是"缓冲"然后,write只能导致字节被写入缓冲区。可能需要致电this.out.flush()至"推送"到服务器。

但我怀疑它会有所帮助,因为(据我所知)套接字输出流不是用Java缓冲的。我认为真正的问题更可能发生在服务器端。

如果您难以确定问题出在哪一方,我建议您尝试使用网络监控/数据包嗅探工具(在服务器端)检查数据是否到达服务器主机。


虽然我引起了你的注意,你的异常代码确实非常糟糕。

  1. 不要将方法声明为throws Throwable(或throws Exception)。这基本上说"这种方法可能会抛出 ANY 异常,而且我不会告诉你哪一个"。当你这样做时,调用者代码必须处理任何异常,这基本上不可能聪明地做。

    应该做的是将方法声明为抛出代码可以抛出的已检查异常。例如,在您的情况下,IOException可能就足够了。

  2. 捕获异常,记录异常然后重新抛出异常并不是一个好主意。为什么?因为堆栈的进一步上升可能会有其他方法可以看到异常。他们无法知道是否已记录异常。所以他们应该记录它(可能导致同一问题的重复日志事件)或不记录(可能导致异常未记录。)

  3. 不要在没有消息的情况下抛出异常:

          throw new IOException();
    

    很懒。您应该始终包含一条简单的信息,该信息可以(至少)被grep&d或者用Google搜索。

  4. 此外,您不必在全处测试Socket.isConnected()。根据javadoc:

      

    返回:如果套接字已成功连接到服务器,则返回true

         

    注意:关闭套接字并不清除其连接状态,这意味着   对于已关闭的套接字,此方法将返回true(请参阅isClosed())if   它在被关闭之前已成功连接。

    因此反复测试isConnected是无效的。如果它返回true一次,那么它将始终返回true

    即使isConnected中的初始setStreams测试也值得怀疑。我只是在没有测试的情况下调用getInputStream,并且如果套接字处于错误的状态,则依赖于Socket API抛出IOException

答案 1 :(得分:1)

您可以使用晦涩的扫描仪使用来有效地阅读线条,但您并未编写线条。因此扫描仪将阻塞,直到线路终结器或EOS到达。

发送时需要附加行终止符。