我试图在我的应用程序中进行一些网络连接,但我遇到了一些问题。似乎我无法写入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() : "";
}
}
答案 0 :(得分:3)
我只能看到一个客户端可能导致这个......我对此表示怀疑。 (也就是说:试试这个,以防它产生差异,但我认为不会。)
this.out.write(message.getBytes());
Log.d("SOCKET","WRITING COMPLETE. " + message);
潜在的问题是如果out
是"缓冲"然后,write
只能导致字节被写入缓冲区。可能需要致电this.out.flush()
至"推送"到服务器。
但我怀疑它会有所帮助,因为(据我所知)套接字输出流不是用Java缓冲的。我认为真正的问题更可能发生在服务器端。
如果您难以确定问题出在哪一方,我建议您尝试使用网络监控/数据包嗅探工具(在服务器端)检查数据是否到达服务器主机。
虽然我引起了你的注意,你的异常代码确实非常糟糕。
不要将方法声明为throws Throwable
(或throws Exception
)。这基本上说"这种方法可能会抛出 ANY 异常,而且我不会告诉你哪一个"。当你这样做时,调用者代码必须处理任何异常,这基本上不可能聪明地做。
应该做的是将方法声明为抛出代码可以抛出的已检查异常。例如,在您的情况下,IOException
可能就足够了。
捕获异常,记录异常然后重新抛出异常并不是一个好主意。为什么?因为堆栈的进一步上升可能会有其他方法可以看到异常。他们无法知道是否已记录异常。所以他们应该记录它(可能导致同一问题的重复日志事件)或不记录(可能导致异常未记录。)
不要在没有消息的情况下抛出异常:
throw new IOException();
很懒。您应该始终包含一条简单的信息,该信息可以(至少)被grep&d或者用Google搜索。
此外,您不必在全处测试Socket.isConnected()
。根据javadoc:
返回:如果套接字已成功连接到服务器,则返回true
注意:关闭套接字并不清除其连接状态,这意味着 对于已关闭的套接字,此方法将返回true(请参阅isClosed())if 它在被关闭之前已成功连接。
因此反复测试isConnected
是无效的。如果它返回true
一次,那么它将始终返回true
。
即使isConnected
中的初始setStreams
测试也值得怀疑。我只是在没有测试的情况下调用getInputStream
,并且如果套接字处于错误的状态,则依赖于Socket
API抛出IOException
。
答案 1 :(得分:1)
您可以使用晦涩的扫描仪使用来有效地阅读线条,但您并未编写线条。因此扫描仪将阻塞,直到线路终结器或EOS到达。
发送时需要附加行终止符。