2013-10-08 3 views
0

Основано на уроке this и еще одном учебнике, к сожалению, я не могу воспользоваться своими руками прямо сейчас, я создал приложение Client-Server, но вместо отправки строковых сообщений клиент запрашивает данные (используя потоки ввода/вывода объекта) с сервера с использованием пользовательского класса «Сообщение».
Сначала я создал базовую концепцию, используя простую Java и протестировал как сервер, так и клиент на своем компьютере, и отобразил данные, полученные моим клиентом на выходе консоли. Все получилось отлично, поэтому я начал переходить на Android (для клиента). Пытаясь использовать AsycTask, как показано в связанном учебнике, мне удалось до сих пор установить соединение между клиентом и сервером. Но у меня возникла проблема с получением моего сервера для чтения моего объекта «Сообщение». Вот мои классы:ClassNotFoundException на сервере при чтении из ObjectInputStream

Сервер:

import java.io.*; 
import java.net.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class T_Server extends Thread { 

    private static int port = 4444; 
    private ServerSocket srvSock = null; 
    private Socket clntSock = null; 
    private boolean running = false; 
    private ObjectInputStream in; 
    private ObjectOutputStream out; 
    private OnMessageReceived msgListener; 
    private Message msgIn; 
    private Object objSend; 


    public static void main(String[] args) { 
     OnMessageReceived _msgListener=new OnMessageReceived(); 
     T_Server server=new T_Server(_msgListener); 

     server.start(); 
    } 


    public T_Server(OnMessageReceived _msgListener) { 
     this.msgListener = _msgListener; 
    } 

    public void send(Object _msg) { 
     if (out != null) { 
      try { 
       out.writeObject(_msg); 
       out.flush(); 
      } catch (IOException ex) { 
       Logger.getLogger(T_Server.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
    } 

    @Override 
    public void run() { 

     running = true; 

     try { 
      srvSock = new ServerSocket(port); 
      System.out.println("Server startet. IP : " + InetAddress.getLocalHost() + ", Port : " + srvSock.getLocalPort()); 
      System.out.println("\nWaiting for a client ..."); 
      clntSock = srvSock.accept(); 
      System.out.println("\nClient accepted: " + clntSock); 

      try { 
       out = new ObjectOutputStream(clntSock.getOutputStream()); 
       in = new ObjectInputStream(clntSock.getInputStream()); 

       while (running) { 
        msgIn = (Message) in.readObject(); 
        System.out.println(msgIn.toString()); 

        objSend = msgListener.messageReceived(msgIn); 
        send(objSend); 
       } 
      } catch (Exception e) { 
       System.out.println("S: Error"); 
       e.printStackTrace(); 
      } finally { 
       clntSock.close(); 
      } 

     } catch (Exception e) { 
      System.out.println("S: Error"); 
      e.printStackTrace(); 
     } 

    } 
} 

Я использую тот же класс сообщений и на сервере и на клиенте класса сообщений:

import java.io.Serializable; 

public class Message implements Serializable{ 

    private static final long serialVersionUID = 1L; 
    public String sender, content, type; 

    public Message(String sender, String type, String content){ 
     this.sender = sender; this.type=type; this.content = content; 
    } 

    @Override 
    public String toString(){ 
     return "{type='"+type+"', sender='"+sender+"', content='"+content+"'}"; 
    } 

} 

Я также создал класс для обработки сообщений на стороне сервера, называемый OnMessageReceived.
P.S. В этом классе есть поля и некоторые параметры, которые связаны с моей базой данных.
OnMessageReceived:

import java.sql.SQLException; 
import java.util.regex.Pattern; 

public class OnMessageReceived { 

    public Object messageReceived(Message message) throws SQLException { 
     Message _msg = message; 
     Database db = new Database(); 
     Object objReturn; 
     String strResult; 
     boolean addResult; 
     final Pattern pattern = Pattern.compile("\\[.*?&"); 
     final String[] result; 
     if (_msg.type.equals("getUsers")) { 
      objReturn = db.getUsers(); 
      return objReturn; 
     } else if (_msg.type.equals("getFriends")) { 
      objReturn = db.getFriends(_msg.sender); 
      return objReturn; 
     } else if (_msg.type.equals("addFriend")) { 
      String _UserName, _UserNameFriend; 
      _UserName = _msg.sender; 
      _UserNameFriend = _msg.content; 
      addResult = db.addFriend(_UserName, _UserNameFriend); 
      if (addResult) { 
       strResult = "Add was successfull"; 
       return strResult; 
      } else if (!addResult) { 
       strResult = "Add failed"; 
       return strResult; 
      } 
      System.out.println(addResult); 
     } else if (_msg.type.equals("addUser")) { 
      String _UserName, _Password, _Phone; 
      result = pattern.split(_msg.content); 
      _UserName = _msg.sender; 
      _Password = result[0]; 
      _Phone = result[1]; 
      addResult = db.addUser(_UserName, _Password, _Phone); 
      if (addResult) { 
       strResult = "Add was successfull"; 
       return strResult; 
      } else if (!addResult) { 
       strResult = "Add failed"; 
       return strResult; 
      } 
      System.out.println(addResult); 
     } else if (_msg.type.equals("Login")) { 
      boolean isUser; 
      String _UserName; 
      _UserName = _msg.sender; 
      isUser = db.isUser(_UserName); 
      if (isUser) { 
       strResult = "Login Successfull"; 
       return strResult; 
      } else if (!isUser) { 
       strResult = "Login failed"; 
       return strResult; 
      } 
     } 
     return null; 
    } 
} 

Для стороне клиента (на Android) это всего напоминает таковой в связанном учебнике. Разница в том, что у меня есть только две кнопки, одна для подключения к серверу и одна для отправки моего сообщения, которое является экземпляром моего класса Message.
Клиент:

import java.io.*; 
import java.net.*; 
import android.util.Log; 


public class T_Client { 
    private static final String TAG = "MyActivity"; 

    private static String serverIP = "192.168.1.11"; 
    private static int port = 4444; 
    private InetAddress serverAddr = null; 
    private Socket sock = null; 
    private boolean running = false; 
    private ObjectInputStream in; 
    private ObjectOutputStream out; 
    private OnMessageReceived msgListener; 
    Object objIn, objReceived; 

    public T_Client(OnMessageReceived _msgListener){ 
     this.msgListener=_msgListener; 
    } 

    public void send(Message _msg) { 
     if (out != null) { 
      try { 
       out.writeObject(_msg); 
       out.flush(); 
       Log.i(TAG,"Outgoing : " + _msg.toString()); 
      } catch (IOException ex) { 
       Log.e(TAG,ex.toString()); 
      } 
     } 
    } 

    public void stopClient(){ 
     running = false; 
    } 

    public void run(){ 
     running = true; 
     try { 
      //here you must put your computer's IP address. 
      serverAddr = InetAddress.getByName(serverIP); 

      Log.i("TCP Client", "C: Connecting..."); 

      //create a socket to make the connection with the server 
      sock = new Socket(serverAddr, port); 

      try { 

       //send the message to the server 
       out =new ObjectOutputStream(sock.getOutputStream());    

       //receive the message which the server sends back 
       in =new ObjectInputStream(sock.getInputStream()); 

       Log.i("TCP Client", "C: Connected."); 

       //in this while the client listens for the messages sent by the server 
       while (running) { 
        objIn = in.readObject(); 

        if (objIn != null && msgListener != null) { 
         //call the method messageReceived from MyActivity class 
         msgListener.messageReceived(objIn); 
        } 
        objIn = null; 

       } 


       Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + objIn + "'"); 


      } catch (Exception e) { 

       Log.e("TCP", "S: Error", e); 

      } finally { 
       //the socket must be closed. It is not possible to reconnect to this socket 
       // after it is closed, which means a new socket instance has to be created. 
       sock.close(); 
      } 

     } catch (Exception e) { 

      Log.e("TCP", "C: Error", e); 

     } 

    } 

    public interface OnMessageReceived { 
     public void messageReceived(Object objReceived); 
    } 

} 

Основная деятельность:

import java.io.IOException; 

import android.os.AsyncTask; 
import android.os.Bundle; 
import android.app.Activity; 
import android.util.Log; 
import android.view.View; 

public class MainActivity extends Activity { 
    private static final String TAG = "MyActivity"; 

    private T_Client client; 
    private Message msgSend; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

    } 

    public void connect(View v) throws IOException {   
     new connectTask().execute(""); 

    } 

    public void btnSend(View v) throws IOException { 
     msgSend=new Message("Setlios", "getUsers", ""); 
     if(client!=null){ 
      client.send(msgSend); 
     } 

    } 


    public class connectTask extends AsyncTask<Object,Object,T_Client> { 

     @Override 
     protected T_Client doInBackground(Object... objIn) { 

      //we create a TCPClient object and 
      client = new T_Client(new T_Client.OnMessageReceived() { 
       @Override 
       //here the messageReceived method is implemented 
       public void messageReceived(Object objIn) { 
        //this method calls the onProgressUpdate 
        publishProgress(objIn); 
       } 
      }); 
      client.run(); 

      return null; 
     } 

     @Override 
     protected void onProgressUpdate(Object... values) { 
      super.onProgressUpdate(values); 

      Log.i(TAG,values.getClass().getName().toString()); 
     } 
    } 

} 

Когда я попал в «Отправить» кнопку Я получаю эту ошибку на консоли сервера, который указывает мне на точку, где я прочитал объект, прочитанный из ObjectInputStream и передающий ему экземпляр класса Message, но я не могу понять, в чем проблема. Я также заметил, что это показывает, что это «in.neverhide.connect», которая является имя пакета проекта для моего андроида клиента

java.lang.ClassNotFoundException: in.neverhide.connect.Message 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:264) 
    at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:622) 
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1593) 
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514) 
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750) 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347) 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369) 
    at Objects_WORKING.T_Server.run(T_Server.java:61) 

ответ

0

Ok после поиска вокруг я нашел this пост и ответ от Akinsola «МЫС Tunmise. Я сделал класс Message в jar и использовал его как внешнюю ссылку как на клиенте, так и на сервере.

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