WiFiP2pServerTask.java 5.4 KB

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