2013-07-03 3 views
0

Я разрабатываю приложение для Android (клиент) и хочу, чтобы он соединился с моим сервером Java, используя TCP-связь, и до сих пор все идет хорошо.Связь TCP-сервера

код сервера:

import java.net.*; 
import java.io.*; 
import globalvariables.GlobalVariables; 
import interface_package.ServerInterface; 
import java.util.Timer; 


/** 
* 
* @author wsserver 
*/ 
public class ThreadedAndroidServer { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 

     GlobalVariables.init(); 
     //Prevzemi staticen interface 
     GlobalVariables.sinterface = new ServerInterface(); 
     GlobalVariables.sinterface.show(); 

     //INFINITE LOOP 
     while(true) 
     int port = GlobalVariables.portNo; 

     ServerSocket serverSocket = null; 
     try { 
      serverSocket = new ServerSocket(port); 
      System.out.println("Server has started listening on port " + port); 
      GlobalVariables.sinterface.setServerStatus("Server has started listening on port " + port); 
     } catch (IOException e) { 
      System.out.println("Error: Cannot listen on port " + port + " : " + e); 
      GlobalVariables.sinterface.setServerStatus("Error: Cannot listen on port " + port + " : " + e); 
      System.exit(1); 
     } 
     while (true) // infinite loop - loops once for each client 
     { 
      Socket clientSocket = null; 
      try { 
       clientSocket = serverSocket.accept(); //waits here (forever) until a client connects 
       System.out.println("Server has just accepted socket connection from a client"); 
       GlobalVariables.sinterface.setServerStatus("Server has just accepted socket connection from a client"); 
      } catch (IOException e) { 
       System.out.println("Accept failed: " + e); 
       GlobalVariables.sinterface.setServerStatus("Accept failed: " + e); 
       break; 
      } 

      // Create the Handle Connection object - our new thread object - only create it 
      ThreadedHandleConnection con = new ThreadedHandleConnection(clientSocket); 

      if (con == null) //If it failed send and error message 
      { 
       try { 
        ObjectOutputStream os = new ObjectOutputStream(clientSocket.getOutputStream()); 
        os.writeObject("error: Cannot open socket thread"); 
        os.flush(); 
        os.close(); 
       } catch (Exception ex) //failed to even send an error message 
       { 
        System.out.println("Cannot send error back to client: " + ex); 
        GlobalVariables.sinterface.setServerStatus("Cannot send error back to client: " + ex); 
       } 
      } else { 
       con.start(); 
      } // otherwise we have not failed to create the HandleConnection object 
      // start this thread now 
     } 

     try // do not get here at the moment 
     { 
      System.out.println("Closing server socket."); 
      GlobalVariables.sinterface.setServerStatus("Closing server socket."); 
      serverSocket.close(); 
     } catch (IOException e) { 
      System.err.println("Could not close server socket. " + e.getMessage()); 
      GlobalVariables.sinterface.setServerStatus("Could not close server socket. " + e.getMessage()); 
     } 


    } 
} 

Подключение Handler:

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package tcpServer_package; 

import java.net.*; 
import java.io.*; 
import java.util.*; 
import busimesslogic_package.Functions; 

/** 
* 
* @author wsserver 
*/ 
public class ThreadedHandleConnection extends Thread { 

    private Socket clientSocket;   // Client socket object 
    private ObjectInputStream is;   // Input stream 
    private ObjectOutputStream os;   // Output stream 

    // The constructor for the connecton handler 
    public ThreadedHandleConnection(Socket clientSocket) { 
     this.clientSocket = clientSocket; 
    } 

    // The main thread execution method 
    public void run() { 


     try { 
      this.is = new ObjectInputStream(clientSocket.getInputStream()); 
      this.os = new ObjectOutputStream(clientSocket.getOutputStream()); 
      while (this.readCommand()) { 
      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    // Receive and process incoming command from client socket 
    private boolean readCommand() { 
     String wholeCommand = null; 

     try { 
      wholeCommand = (String) is.readObject(); 
     } catch (Exception e) { 
      wholeCommand = null; 
     } 
     if (wholeCommand == null) { 
      this.closeSocket(); 
      return false; 
     } 
     System.out.println("Received: "+wholeCommand); 
     //GET COMMAND PARAMETARS 
     String[] commParams = wholeCommand.split(";"); 

     //GET COMMAND TYPE 
     int type = Integer.parseInt(commParams[0]); 

     //SELECT COMMAND PROCEDURE 
     Functions functions = new Functions(); 
     String IPaddress = clientSocket.getRemoteSocketAddress().toString(); 
     IPaddress = IPaddress.substring(IPaddress.indexOf("/")+1, IPaddress.indexOf(":")); 

     switch (type) { 
      case 1: { 
       String sendText = getTextToSend(); 
       send(sendText); 
       break; 
      } 
      default:{ 
       sendError("0;"+wholeCommand); 
       break; 
      } 
     } 
     System.gc(); 
     return true; 
    } 
    // Send a message back through to the client socket as an Object 

    private void send(Object o) { 
     try { 
      System.out.println("Sending " + o); 
      this.os.writeObject(o); 
      this.os.flush(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    // Send a pre-formatted error message to the client 
    public void sendError(String msg) { 
     this.send("error:" + msg); //remember a string IS-A object! 
    } 

    // Close the client socket 
    public void closeSocket() //close the socket connection 
    { 
     try { 
      this.os.close(); 
      this.is.close(); 
      this.clientSocket.close(); 
     } catch (Exception ex) { 
      System.err.println(ex.toString()); 
     } 
    } 
} 

Android код клиента:

package com.example.zpbitolaoperator; 

import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 

import java.net.Socket; 

import android.util.Log; 

public class TCPClient{ 

    //Comunication variables 
    private static Socket socket; 
    private static ObjectOutputStream os; 
    private static ObjectInputStream is; 

    //Server parametars 
    static String serverIP; 
    static int port; 

    //Communication status 
    static boolean connectionStatus = false; 

    public static boolean connectToServer() { 
     try // open a new socket to port: and create streams 
     { 

      serverIP = GlobalVariables.serverIP; 
      port = GlobalVariables.portNo; 

      socket = new Socket(serverIP, port); 
      os = new ObjectOutputStream(socket.getOutputStream()); 
      is = new ObjectInputStream(socket.getInputStream()); 
      Log.d("DEBUG", "Connected to Server"); 
      connectionStatus = true; 
      return true; 

     } catch (Exception ex) { 
      Log.d("DEBUG", "Failed to Connect to Server " +ex.toString(), ex.getCause()); 
      connectionStatus = false; 
      return false; 
     } 

    } 

    public static boolean closeConnection(String message){ 
     try{ 
      socket.close(); 
      Log.d("DEBUG", "Closed connection to Server"); 
      return true; 
     } catch (Exception ex){ 
      Log.d("DEBUG", "Failed to close connection to Server " +ex.toString(), ex.getCause()); 
      return false; 
     } 

    } 
    private static String sendMessage(String message) { 
     String returnString; 
     send(message); 
     returnString = (String) receive(); 
     if (returnString != null) { 
      Log.d("DEBUG", "Server returned: " + returnString); 
     }else{ 
      return returnString = "ERROR"; 
     } 
     return returnString; 
    } 

    // method to send a generic object. 
    private static void send(Object o) { 
     try { 
      Log.d("DEBUG", "Sending: " + o); 
      os.writeObject(o); 
      os.flush(); 
     } catch (Exception ex) { 
      Log.d("DEBUG", "Sending to server " +ex.toString(), ex.getCause()); 
     } 
    } 

    // method to receive a generic object. 
    private static Object receive() { 
     Object o = null; 
     try { 
      o = is.readObject(); 
     } catch (Exception ex) { 
      Log.d("DEBUG", "Receive from server " +ex.toString(), ex.getCause()); 
     } 
     return o; 
    } 
    /** 
    * Isprakja poraka do server 
    * @param message 
    * @return ili ERROR ili poraka 
    */ 
    public synchronized static String sendToServer(String message) { 

     String rez = ""; 
     try { 
      rez = sendMessage(message); 
     } catch (Exception ex) { 
      Log.d("DEBUG", "Send to server " +ex.toString(), ex.getCause()); 
     } 
     return rez; 
    } 

    public static boolean getCommunicationStatus(){ 
     return connectionStatus; 
    } 
} 

Я посылаю данные строковых на мой сервер (Comand; param1; Param2. ...), сервер обрабатывает эти данные и возвращает некоторые данные для приложения Android. Приложение Android - это TCP-клиент, а Java-приложение - сервер. Для каждого соединения сервер создает поток (бесконечный), который обрабатывает это соединение. Проблема в том, что мой сервер не может отправить что-то без отправки клиентом запроса. ObjectInputStream readObject() блокирует поток, пока клиент не отправит некоторые данные. Я хочу использовать тот же сокет для отправки в другом направлении (java -> android и приложение Android отправить некоторые данные обратно). Я знаю, что это можно сделать, открыв другой сокет, где Android будет сервером и Java-приложением будет клиентом. Это возможно и как?

+0

Вы должны иметь возможность установить тайм-аут в сокете на сервере, чтобы принудительно продолжить. – ThaMe90

ответ

0

Если вы хотите, чтобы иметь возможность одновременно получать данные от клиента и отправить данные клиенту, то вам придется либо использовать два потока на клиента (один для приема и один, чтобы отправить) или использовать non-blocking IO.

Смежные вопросы