简体   繁体   English

Android套接字已连接但无法写入

[英]Android socket connects but cant write to it

I was trying to get some networking going in my app, but i encountered some issues. 我试图在我的应用程序中进行一些联网,但是遇到一些问题。 It seems that I cant write to the OutputStream object. 看来我无法写入OutputStream对象。 Though my server recieves the connection, it does not recieve any data. 尽管我的服务器接收到该连接,但它没有接收到任何数据。 I've tried using Writer, DataOutputStream among others. 我试过使用Writer,DataOutputStream等。 none seemed to work. 似乎没有一个工作。 My app uses asynctasks that call this object with a Socket object and a message. 我的应用程序使用异步任务,该任务通过Socket对象和消息来调用此对象。 (The socket object has already been used to set Streams after initialisation using the setStreams method.) can someone please try and find the problem? (使用setStreams方法初始化后,套接字对象已经用于设置Streams。)有人可以尝试查找问题吗? I will be very thankful. 我将非常感谢。

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() : "";
}

} }

I can only see one client-side that might cause this ... and I'm doubtful about it. 我只能看到一个可能导致此问题的客户端...,对此我表示怀疑。 (That is to say: try this, just in case it makes a differences, but I don't think it will.) (这就是说:尝试一下,以防万一它有所作为,但我认为不会。)

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

The potential problem is that if out is a "buffered" stream, then a write may only result in the bytes being written to the buffer. 潜在的问题是,如果out是“缓冲”流,则write可能只会导致将字节写入缓冲区。 It may be necessary to call this.out.flush() to "push" to the server. 可能需要调用this.out.flush()以“推送”到服务器。

But I am doubtful it will help, because (to my knowledge) a socket output stream isn't buffered in Java. 但是我怀疑它是否会有所帮助,因为(据我所知)套接字输出流没有在Java中缓冲。 I think it is more likely that the real problem is on the server side. 我认为真正的问题更有可能在服务器端。

If you are stumped with figuring out which side the problem is occuring, I suggest you try using a network monitoring / packet sniffing tool (on the server side) to check if the data is reaching the server host. 如果您不知道该问题出在哪一边,建议您尝试使用网络监视/数据包嗅探工具(在服务器端)检查数据是否到达服务器主机。


While I have your attention, your exception code is really, really bad. 在引起您注意的同时,您的异常代码确实非常糟糕。

  1. Don't declare methods as throws Throwable (or throws Exception ). 不要throws Throwable声明为throws Throwable (或throws Exception )。 That basically says "this method may throw ANY exception, and I'm not telling you which one". 基本上就是说“此方法可能会抛出任何异常,而我没有告诉您是哪个”。 When you do that, the caller code has to cope with any exception, which is basically impossible to do intelligently. 当您执行此操作时,调用者代码必须处理任何异常,这基本上不可能明智地执行。

    What you should do is to declare the method as throwing the checked exceptions that the code can throw. 应该做的是将方法声明为抛出代码可以抛出的已检查异常。 For example, in your case, IOException is probably sufficient. 例如,在您的情况下, IOException可能就足够了。

  2. It is not a good idea to catch an exception, log it, and then rethrow it. 捕获异常,记录并重新抛出异常不是一个好主意。 Why? 为什么? Because further up the stack there are probably other methods that will see the exception. 因为在堆栈的更远处,可能还有其他方法将看到异常。 They can't know if the exception has already been logged or not. 他们不知道该异常是否已经记录。 So should they log it (possibly resulting in duplicate logs events for the same problem) or not (possibly resulting in the exception going unlogged.) 因此,他们应该记录它(可能导致相同问题的重复日志事件)还是不记录(可能导致未记录的异常)。

  3. Don't throw exceptions without a message: 不要在没有消息的情况下抛出异常:

      throw new IOException(); 

    It is lazy. 很懒 You should always include a simple message that can (at least) be grep'd or googled for. 您应该始终包含一条简单的消息,该消息至少可以被grep或google搜索。

In addition, your testing of Socket.isConnected() all over the place is unnecessary. 此外,您无需在整个位置测试Socket.isConnected() According to the javadoc: 根据javadoc:

Returns: true if the socket was successfuly connected to a server 返回:如果套接字已成功连接到服务器,则返回true

Note: Closing a socket doesn't clear its connection state, which means this method will return true for a closed socket (see isClosed()) if it was successfuly connected prior to being closed. 注意:关闭套接字不会清除其连接状态,这意味着如果已关闭的套接字在关闭之前已成功连接,则此方法将对关闭的套接字返回true(请参见isClosed())。

So repeatedly testing isConnected is nugatory. 因此,反复测试isConnected是无效的。 If it returns true once, it will will always return true from then on. 如果返回true一次,它会总是返回true从那时起。

Even the initial isConnected test in setStreams is doubtful. 甚至setStreams的初始isConnected测试都是可疑的。 I'd just call getInputStream without testing, and rely on the Socket API throwing an IOException if the socket is in the wrong state. 我只是调用getInputStream而不进行测试,并且如果套接字处于错误状态,则依靠Socket API抛出IOException

You're effectively reading lines with that obscure Scanner usage, but you're not writing lines. 您实际上是在使用晦涩的Scanner使用来读取行,但不是在编写行。 So the scanner will block until a line terminator or EOS arrives. 因此,扫描仪将阻塞直到行终止器或EOS到达为止。

You need to append a line terminator when sending. 发送时需要附加行终止符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM