[英]Cannot receive data from socket opened programmatically
已解決 :第一次連接后,我沒有重新啟動服務器。 現在它工作得很漂亮;)
我在Android設備和PC之間的TCP連接方面遇到麻煩。 在PC上,我有一個帶有ServerSocket等待接受的tcp服務器,並且本地網絡中的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");
}
}
這里我有IpGetter類,該類具有用於從本地網絡動態獲取IP的方法getIp():
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(),....
有人知道如何管理嗎? 感謝幫助。
好的,我解決了。 原來,我沒有為IpGetter打開套接字后才重新啟動服務器。 現在我完成了!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.