2013-07-03 174 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