我对一个只是拒绝正确刷新的java.net.SocketOutputStream感到沮丧!我必须忽视显而易见的事。在我下面的Groovy脚本中,我尝试连接到在我的Galaxy Nexus Android 4.0.2手机上运行的简单套接字服务器,它在我的5秒超时到期后立即给出了套接字关闭异常。
SocketClient.groovy
import java.net.*
socket = new Socket()
socket.connect(new InetSocketAddress(InetAddress.getByAddress([172,17,57,21] as byte[]), 58789), 5000)
println "Connected!"
socket.withStreams { input, output ->
println "Processing ${input.class.name} and ${output.class.name} streams..."
output.withWriter {
it << 'echo testing\n\n';
it.flush();
output.flush()
def readerThread = Thread.start {
println "Request written, reading response..."; println input.text
}
println "Waiting 5 secs for read to complete."
readerThread.join(5000)
}
println "Stream closed!"
}
我尝试了所有不同的刷新方法,包括将输出流直接刷新到使用writer和冲洗的间接包装。在流关闭之前,服务器上不会显示任何数据,导致套接字关闭,从而导致任何从套接字读取的尝试崩溃。我究竟做错了什么?我也会在下面列出我的Android代码。这是一个启动套接字服务器的简单活动。
MyServer.java
package com.example;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MyServer extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
RawSocketServer rawSocketServer = new RawSocketServer();
String port = rawSocketServer.getLocalPort();
TextView textView = (TextView) this.findViewById(R.id.mainTextView);
textView.setText("Server bound to port " + port);
rawSocketServer.start();
}
}
RawSocketServer.java
package com.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by IntelliJ IDEA.
* User: cliff
* Date: 5/9/12
* Time: 4:03 PM
*/
public class RawSocketServer {
public static final int PORT = 0;
private ServerSocket serverSocket;
public RawSocketServer() {
this(PORT);
}
public RawSocketServer(int port) {
try {
this.serverSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("server cannot bind to port " + port);
}
}
public void start() {
new Thread(new Runnable() {
public void run() {
go();
}
}).start();
}
private void go() {
Socket socket = null;
while (true) {
try {
socket = this.serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("cannot accept from server socket" + e);
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Could not get input stream from socket. " + e);
}
PrintWriter writer = null;
try {
writer = new PrintWriter(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Could not get output stream from socket. " + e);
}
try {
for (String line = reader.readLine(); line !=null; line = reader.readLine()) {
writer.print(line);
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Error reading/writing from/to socket. " + e);
}
}
}
public String getLocalPort() {
return "" + serverSocket.getLocalPort();
}
}
答案 0 :(得分:1)
我在想......你在那里“它&lt;&lt;&lt;&lt;''回声测试'”。在Writer上使用它意味着afaik没有写入行结尾。由于您的服务器使用readLine,因此它期望一行结束。因此数据可能会到达,但readLine没有完成,因为它等待行的结束。然后修复例如“it&lt;&lt;&lt;&lt;'echo testing \ n'”或“it&lt;&lt;&lt;&lt;&lt;&lt;'&lt;'\ n \ n'”。
现在我不太了解Android API,但是你的服务器可能在“writer.print(line);”中遇到同样的问题,因为我认为用readLine读取一行,不包含行结尾了。但由于这不再被阅读,目前应该没有问题。
答案 1 :(得分:1)
我终于在Blackdrag的帮助下弄明白这一点。我的问题出在多个方面。由于缺少换行符,客户端读取将挂起(建议使用blackdrag)。服务器读取循环也会挂起,因为客户端永远不会关闭其写入流。这导致了鸡和蛋的问题,其中关闭写入流关闭了关闭读取流的套接字。我最终需要输入&#34;协议&#34;,如果你愿意,这将表明会话何时完成,服务器应该停止读取,从而关闭套接字。写完&#34;完成&#34;客户端上的字符串成为该指标。工作客户端和服务器的完整来源如下:(我知道这是非常糟糕的Android代码,但最初只是为了测试我的新Galaxy Nexus上的通信,我还在学习如何使用iOS版本!)
SocketClient.groovy
import java.net.*
socket = new Socket()
socket.connect(new InetSocketAddress(InetAddress.getByAddress([172,17,57,21] as byte[]), 58302), 5000)
println "Connected!"
socket.withStreams { input, output ->
println "Processing ${input.class.name} and ${output.class.name} streams..."
output.withWriter {
it << 'my name is cliff\ndone\n';
it.flush();
output.flush()
def readerThread = Thread.start {
println "Request written, reading response..."; println input.text
}
println "Waiting 5 secs for read to complete."
readerThread.join(60000)
}
println "Stream closed!"
}
MyServer.java
package com.example;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MyServer extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
RawSocketServer rawSocketServer = new RawSocketServer();
String port = rawSocketServer.getLocalPort();
TextView textView = (TextView) this.findViewById(R.id.mainTextView);
textView.setText("Server bound to port " + port);
rawSocketServer.start();
}
}
RawSocketServer.java
package com.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by IntelliJ IDEA.
* User: cliff
* Date: 5/9/12
* Time: 4:03 PM
*/
public class RawSocketServer {
public static final int PORT = 0;
private ServerSocket serverSocket;
public RawSocketServer() {
this(PORT);
}
public RawSocketServer(int port) {
try {
this.serverSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("server cannot bind to port " + port);
}
}
public void start() {
new Thread(new Runnable() {
public void run() {
go();
}
}).start();
}
private void go() {
Socket socket = null;
while (true) {
try {
socket = this.serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("cannot accept from server socket" + e);
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Could not get input stream from socket. " + e);
}
PrintWriter writer = null;
try {
writer = new PrintWriter(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Could not get output stream from socket. " + e);
}
try {
for (String line = reader.readLine(); line !=null; line = reader.readLine()) {
if(line.trim().equalsIgnoreCase("done")) break;
writer.println(line);
writer.flush();
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Error reading/writing from/to socket. " + e);
}
}
}
public String getLocalPort() {
return "" + serverSocket.getLocalPort();
}
}