0

このチュートリアルと、残念ながら今は手に入らない別のチュートリアルに基づいて、クライアント サーバー アプリケーションを作成しましたが、文字列メッセージを送信する代わりに、クライアントは (オブジェクト入力/出力ストリームを使用して) データを要求し ますカスタムクラス「メッセージ」を使用してサーバー。
最初に、単純な Java を使用してその基本概念を作成し、サーバーとクライアントの両方をコンピューターでテストし、クライアントが受け取ったデータをコンソール出力に表示しました。すべてがうまくいったので、Android(クライアント用)への移行を開始しました。リンクされたチュートリアルに示されているように、AsycTask を使用しようとして、クライアントとサーバー間の接続を確立することができました。しかし、サーバーに「メッセージ」オブジェクトを読み取らせるのに問題があります。

サーバ:

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 というメッセージを処理するクラスも作成しました。
PS このクラスには、バックエンド データベースに関係するフィールドといくつかのオプションがあります。
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 クラスのインスタンスであるメッセージを送信するためのボタンの 2 つしかないことです。
クライアント:

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 クラスのインスタンスを渡すポイントが示されますが、何が問題なのか理解できません。 . また、Androidクライアントのプロジェクトのパッケージ名であるこの「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)
4

1 に答える 1