WiFiP2pServerTask.java 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package de.tudarmstadt.informatik.hostage.sync.wifi_direct;
  2. import android.net.wifi.p2p.WifiP2pDevice;
  3. import android.net.wifi.p2p.WifiP2pManager;
  4. import android.util.Log;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.ObjectInputStream;
  8. import java.io.ObjectOutputStream;
  9. import java.io.OutputStream;
  10. import java.net.InetSocketAddress;
  11. import java.net.ServerSocket;
  12. import java.net.Socket;
  13. import de.tudarmstadt.informatik.hostage.R;
  14. import de.tudarmstadt.informatik.hostage.ui.activity.MainActivity;
  15. /**
  16. * Created by Julien on 07.01.2015.
  17. *
  18. * The Server Task.
  19. *
  20. * The Server task is waiting as long as a client is connecting to it.
  21. * As a result of this the main part and process will start after the client had send the first data.
  22. *
  23. * You never know how will become the host / server.
  24. * So you need to implement a strategy if you want do send just from one specific device to the other.
  25. *
  26. * * The server creates the object stream before the client can do it - to avoid a chicken and egg problem.
  27. */
  28. public abstract class WiFiP2pServerTask extends BackgroundTask {
  29. public static String ERROR_MESSAGE_UNKNOWN = MainActivity.getContext().getString(R.string.ERROR_MESSAGE_UNKNOWN);
  30. public static String ERROR_COMMUNICATION_FAILED = MainActivity.getContext().getString(R.string.ERROR_COMMUNICATION_FAILED);
  31. public static String ERROR_CONNECTION_FAILED = MainActivity.getContext().getString(R.string.ERROR_CONNECTION_FAILED);
  32. public static String ERROR_CONNECTION_TIMEOUT = MainActivity.getContext().getString(R.string.ERROR_CONNECTION_TIMEOUT);
  33. static int DEFAULT_TIMEOUT = 15;
  34. private ServerSocket serverSocket;
  35. private WifiP2pDevice ownDevice;
  36. public int getTimeoutSeconds() {
  37. return timeoutSeconds;
  38. }
  39. /**
  40. * Set the time out seconds to
  41. * -1 for infinity
  42. * 0 for defaut 15 seconds
  43. * 1 or more for other seconds
  44. * @param timeoutSeconds the seconds to wait for an request before time ist out.
  45. */
  46. public void setTimeoutSeconds(int timeoutSeconds) {
  47. if (timeoutSeconds == 0) {
  48. this.timeoutSeconds = DEFAULT_TIMEOUT;
  49. } else {
  50. this.timeoutSeconds = timeoutSeconds;
  51. }
  52. }
  53. private int timeoutSeconds;
  54. @Override
  55. public void interrupt(boolean b){
  56. super.interrupt(b);
  57. if (b && this.serverSocket != null) {
  58. try {
  59. this.serverSocket.close();
  60. } catch (IOException e) {
  61. String message = e.getLocalizedMessage() != null? e.getLocalizedMessage() : ERROR_MESSAGE_UNKNOWN;
  62. Log.e("DEBUG_WiFiP2p", "ServerTask - " + message);
  63. }
  64. }
  65. }
  66. public WiFiP2pServerTask( WifiP2pDevice ownDevice, BackgroundTaskCompletionListener l){
  67. super(l);
  68. this.timeoutSeconds = DEFAULT_TIMEOUT;
  69. this.ownDevice = ownDevice;
  70. }
  71. @Override
  72. public String performInBackground(){
  73. while (!this.isInterrupted()){
  74. try {
  75. this.serverSocket = new ServerSocket(WiFiP2pClientTask.port());
  76. //serverSocket.setReuseAddress(true);
  77. //serverSocket.bind(new InetSocketAddress(WiFiP2pClientTask.port()));
  78. Log.d("DEBUG_WiFiP2p", "ServerTask - Socket opened");
  79. this.serverSocket.setSoTimeout(this.getTimeoutSeconds() * 1000);
  80. Socket client = this.serverSocket.accept();
  81. Log.d("DEBUG_WiFiP2p", "ServerTask - connection done");
  82. this.handleConnection(client, this.serverSocket);
  83. client.close();
  84. serverSocket.close();
  85. return BACKGROUND_TASK_MESSAGE_SUCCESS;
  86. } catch (ClassNotFoundException e){
  87. e.printStackTrace();
  88. Log.e("DEBUG_WiFiP2p", "ServerTask - " + e.getMessage());
  89. String e_message = null;
  90. e_message = e.getLocalizedMessage();
  91. if (e_message == null){
  92. e_message = ERROR_COMMUNICATION_FAILED;// COMMUNICATION_ERROR
  93. }
  94. return e_message;
  95. } catch (IOException e) {
  96. try {
  97. if (!this.serverSocket.isClosed()) this.serverSocket.close();
  98. }catch (IOException ec){
  99. Log.e("DEBUG_WiFiP2p", "ServerTask - Could not close server socket.");
  100. }
  101. e.printStackTrace();
  102. Log.e("DEBUG_WiFiP2p", "ServerTask - " + e.getMessage());
  103. String e_message = e.getLocalizedMessage();
  104. if (e_message == null){
  105. e_message = ERROR_MESSAGE_UNKNOWN;// UNKNOWN_ERROR
  106. }
  107. return e_message;
  108. }
  109. }
  110. return BACKGROUND_TASK_MESSAGE_SUCCESS;
  111. }
  112. /**
  113. * The server creates the object stream before the client can do it to avoid a chicken and egg problem.
  114. * @param client the client socket.
  115. * @param server the server socket.
  116. * @throws IOException
  117. * @throws ClassNotFoundException
  118. */
  119. private void handleConnection(Socket client, ServerSocket server) throws IOException, ClassNotFoundException {
  120. OutputStream os = client.getOutputStream();
  121. ObjectOutputStream oos = new ObjectOutputStream(os);
  122. oos.flush();
  123. InputStream is = client.getInputStream();
  124. ObjectInputStream ois = new ObjectInputStream(is);
  125. Object obj = ois.readObject();
  126. while (obj != null && obj instanceof WiFiP2pSerializableObject) {
  127. WiFiP2pSerializableObject receivedObj = ( WiFiP2pSerializableObject) obj;
  128. obj = null;
  129. WiFiP2pSerializableObject toSend = this.handleReceivedObject(receivedObj);
  130. if (toSend != null) {
  131. toSend.setActingDevice_IP_address(this.ownDevice.deviceAddress);
  132. oos.writeObject(toSend);
  133. oos.flush();
  134. oos.reset();
  135. }
  136. try {
  137. obj = ois.readObject();
  138. }catch (IOException e){
  139. // IF NULL WAS TRANSMITTED
  140. obj = null;
  141. }
  142. }
  143. oos.close();
  144. os.close();
  145. ois.close();
  146. is.close();
  147. }
  148. /**
  149. * This method will be called if the server receives data from the client.
  150. * Always return a WiFiP2pSerializableObject instance to give a simple response, otherwise the connection will be disconnected.
  151. * @param receivedObj WiFiP2pSerializableObject the clients request
  152. * @return WiFiP2pSerializableObject the response
  153. */
  154. abstract public WiFiP2pSerializableObject handleReceivedObject(WiFiP2pSerializableObject receivedObj);
  155. }