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應用程序將成爲客戶。這是可行的和如何?
您應該能夠在服務器上的套接字上設置超時以強制其繼續。 – ThaMe90