2013-07-03 175 views
0

我正在開發一個Android應用程序(客戶端),並希望它使用TCP通信與我的Java服務器連接,到目前爲止一切進展順利。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()); 
     } 


    } 
} 

連接處理程序:

/* 
* 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;參數1,參數2。 ...),服務器處理該數據並返回一些數據做Android應用程序。 android應用程序是TCP客戶端,java應用程序是服務器。對於每個連接,服務器創建處理該連接的線程(無限)。問題是,我的服務器不能發送一些沒有客戶端發送請求的東西。 ObjectInputStream readObject()阻塞線程,直到客戶端發送一些數據。我想用相同的套接字發送另一個方向(java-> android和android應用程序發回一些數據)。我知道這可以通過打開另一個套接字來完成,Android將作爲服務器和java應用程序將成爲客戶。這是可行的和如何?

+0

您應該能夠在服務器上的套接字上設置超時以強制其繼續。 – ThaMe90

回答

0

如果您希望能夠從客戶端將數據發送到客戶端同時接收數據,那麼你就必須要麼使用每個客戶端的兩個線程(一個接收和一個發送)或使用non-blocking IO