0
已解決:首次連接後,我沒有重新啓動服務器。現在它工作得很好;)無法通過編程方式接收來自套接字的數據
我在Android設備和PC之間的TCP連接時遇到了麻煩。在PC上,我有tcp服務器與ServerSocket等待接受,並嘗試連接到本地網絡的Android設備。當我將靜態IP地址添加到代碼中時,一切正常,但是當我通過編程(在硬編碼端口上從0到255搜索192.168.1.x)時,它接受連接,但是我無法從ServerSocket接收數據,也無法接收數據來自Android套接字。
在Android上我有3個按鈕的Widget,所有的通信都由AsyncTasks處理。這裏是TCP服務器:
public class TCPClient {
private static final String TAG = "TCPClient";
private final Handler mHandler;
private String ipNumber;
BufferedReader in;
PrintWriter out;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;
private String serverMessage,command;
public TCPClient(Handler mHandler, String command, String ipNumber, OnMessageReceived listener) {
mMessageListener = listener;
this.ipNumber = ipNumber;
this.command = command;
this.mHandler = mHandler;
}
public void sendMessage(String message){
if (out != null && !out.checkError()) {
out.println(message);
out.flush();
mHandler.obtainMessage(MainActivity.SENDING);
Log.d(TAG, "Sent Message: " + message);
}
}
public void stopClient(){
mRun = false;
}
public void run() {
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(ipNumber);
Log.d(TAG, "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, 4444);
try {
//send the message to the server
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
Log.d("TCP Client", "C: Sent.");
Log.d("TCP Client", "C: Done.");
//receive the message which the server sends back
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.sendMessage(command);
//in this while the client listens for the messages sent by the server
while (mRun) {
serverMessage = in.readLine();
Log.d("TCP", "S: Received Message: '" + serverMessage + "'");
if (serverMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(serverMessage);
}
serverMessage = null;
}
Log.d("TCP", "S: Received Message: '" + serverMessage + "'");
} catch (Exception e) {
Log.d("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
out.flush();
out.close();
in.close();
socket.close();
Log.d("TCP", "Socket Closed");
}
} catch (Exception e) {
Log.d("TCP", "C: Error", e);
}
}
//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
//class at on asynckTask doInBackground
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
這裏我的AsyncTask啓動和處理連接:
public class ShutdownAsyncTask extends AsyncTask<String, String, TCPClient> {
private static final String COMMAND = "shutdown -s";
private TCPClient tcpClient;
private Handler mHandler;
private static final String TAG = "ShutdownAsyncTask";
public ShutdownAsyncTask(Handler mHandler){
this.mHandler = mHandler;
}
@Override
protected TCPClient doInBackground(String... params) {
Log.d(TAG, "In do in background");
try{
tcpClient = new TCPClient(mHandler,COMMAND, new IpGetter().getIp(), new TCPClient.OnMessageReceived() {
@Override
public void messageReceived(String message) {
publishProgress(message);
}
});
}catch (NullPointerException e){
Log.d(TAG, "Caught null pointer exception");
e.printStackTrace();
}
tcpClient.run();
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
Log.d(TAG, "In progress update, values: " + values);
if(values.equals("connected")){
tcpClient.sendMessage(COMMAND);
tcpClient.stopClient();
mHandler.obtainMessage(MainActivity.SHUTDOWN);
}else{
tcpClient.sendMessage("wrong");
mHandler.obtainMessage(MainActivity.ERROR);
tcpClient.stopClient();
}
}
@Override
protected void onPostExecute(TCPClient result){
super.onPostExecute(result);
Log.d(TAG, "In on post execute");
}
}
在這裏,我有了方法getIp IpGetter類()用於從本地網絡動態獲取IP:
public class IpGetter {
private static Future<String> portIsOpen(final ExecutorService es, final String ip, final int port, final int timeout) {
Log.d("IpGetter", "In portIsOpen");
return es.submit(new Callable<String>() {
@Override public String call() {
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(ip, port), timeout);
socket.close();
Log.d("portIsOpen", "ip: " + ip);
return ip;
} catch (Exception ex) {
return null;
}
}
});
}
public static String getIp(){
final ExecutorService es = Executors.newFixedThreadPool(20);
final int timeout = 200;
final int port = 4444;
final List<Future<String>> futures = new ArrayList<Future<String>>();
for (int i = 0; i <= 255; i++) {
String ip = "192.168.1."+i;
futures.add(portIsOpen(es, ip, port, timeout));
}
es.shutdown();
for (final Future<String> f : futures) {
try {
if (f.get() != null) {
Log.d("F get", f.get());
return f.get();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return null;
}
}
在服務器端一切都很好。
try{
tcpClient = new TCPClient(mHandler,COMMAND, "192.168.1.103",...
要:
try{
tcpClient = new TCPClient(mHandler,COMMAND, new IpGetter().getIp(),....
有誰知道如何管理它,當我改變了一切正在發生變化?感謝幫助。