Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android NIO服务器选择器在未发送消息时读取_Java_Android_Sockets - Fatal编程技术网

Java Android NIO服务器选择器在未发送消息时读取

Java Android NIO服务器选择器在未发送消息时读取,java,android,sockets,Java,Android,Sockets,我正在尝试使用NIO服务器读/写TCP连接的客户端。我已成功连接,我的初始消息已发送到服务器并正确处理。它说服务器正在发回一条消息,但我在客户端没有收到任何输入。此外,在服务器发回消息后,应用程序崩溃,表示它试图读取空指针(服务器代码第127行) 需要注意的是,我对这个概念还不太熟悉,我并不真正理解选择器。我看过教程,但矛盾的信息让我在这个问题上更加困惑。如果有人有关于这个主题的好教程,我将非常感激 这是我的密码 客户端主活动屏幕 package com.example.client; imp

我正在尝试使用NIO服务器读/写TCP连接的客户端。我已成功连接,我的初始消息已发送到服务器并正确处理。它说服务器正在发回一条消息,但我在客户端没有收到任何输入。此外,在服务器发回消息后,应用程序崩溃,表示它试图读取空指针(服务器代码第127行)

需要注意的是,我对这个概念还不太熟悉,我并不真正理解选择器。我看过教程,但矛盾的信息让我在这个问题上更加困惑。如果有人有关于这个主题的好教程,我将非常感激

这是我的密码

客户端主活动屏幕

package com.example.client;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.example.client.ServerService.Connect;



public class MainActivity extends Activity {

    Button button;
    TextView textView;
    EditText editText;
    EditText editTextps;
    static Handler handler;
    Connect connect=null;
    Object myLock=new Object();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=(Button) findViewById(R.id.button1);
        textView=(TextView) findViewById(R.id.textView1);
        editText=(EditText) findViewById(R.id.editText1);
        editTextps=(EditText) findViewById(R.id.editText2);
        handler=new Handler(){
            @Override
            public void handleMessage(Message msg) { //Handle code for receiving messages 
                super.handleMessage(msg);//when a message is received it's input is processed here
                Bundle bundle=msg.getData();
                if(bundle.getInt("int") == 2){
                    if(bundle.getInt("valid") == 1){
                        Intent i = new Intent();
                        i.setClassName("com.example.client",
                                "com.example.client.ReadyScreen");
                        startActivity(i);
                    }else{
                        alertMessage(); 
                        editText.setText("");
                        editTextps.setText("");
                    }
                }
            }

        };

        startService(new Intent(getBaseContext(), ServerService.class));


        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                String str=editText.getText().toString();
                String strps=editTextps.getText().toString();
                Message msg=Message.obtain();
                Bundle bundle=new Bundle();
                bundle.putString("name", str);
                bundle.putString("password", strps);
                msg.setData(bundle);
                ServerService.threadHandler.sendMessage(msg);
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    public void alertMessage() {

        final android.app.AlertDialog.Builder show = new AlertDialog.Builder(this).setTitle("Error").setMessage("Wrong username/password").setNeutralButton("close", null);
        show.show();
    }
}
运行连接和IO的服务器服务

package com.example.client;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

public class ServerService extends Service {

    Handler handler;
    static MyHandle threadHandler;
    Connect connect=null;
    Object myLock=new Object();
    static SocketChannel socketChannel=null;
    public ByteBuffer sendBuffer=ByteBuffer.allocate(1024);
    static ByteBuffer receiveBuffer=ByteBuffer.allocate(1024);
    static Selector selector;
    private static final String TAG = ServerService.class.getSimpleName();

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        Log.d(TAG, "Started running the service");
        System.out.println(TAG + "Started running the service");

        (new Thread(new ReceivingThread())).start();
        (new Thread(new SendingThread())).start();

        return START_STICKY;
    }


    @Override 
    public void onDestroy(){
        super.onDestroy();
        Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();  
    }

    class Connect {
        SocketChannel socketChannel=null;
        public ByteBuffer sendBuffer=ByteBuffer.allocate(1024);
        ByteBuffer receiveBuffer=ByteBuffer.allocate(1024);
        Selector selector;
        public Connect() {

            try {
                socketChannel=SocketChannel.open();
                SocketAddress remoteAddress=new InetSocketAddress("192.168.2.17", 20001);
                socketChannel.connect(remoteAddress);
                socketChannel.configureBlocking(false);
                selector=Selector.open();
                socketChannel.register(selector, SelectionKey.OP_READ);
            } catch (Exception e) {

                e.printStackTrace();
            }
        }
    }

    public class ReceivingThread implements Runnable{

        @Override
        public void run() {
            Log.d(TAG, "Started running the receive thread");
            connect=new Connect();
            try {
                while(true){
                    if(connect.selector.select()==0)
                        continue;
                    Play receivedMessage = new Play();
                    receivedMessage.play();
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
            }
        }

    }

    public class SendingThread implements Runnable{

        @Override
        public void run() {
            Log.d(TAG, "Started running the send thread");
            Looper.prepare();
            threadHandler=new MyHandle(Looper.myLooper());
            Looper.loop();
        }

    }

    class MyHandle extends Handler{  
        public MyHandle(){
        }
        public MyHandle(Looper looper){ 
                    super(looper);
        }
        public void handleMessage(Message msg){
            String str=msg.getData().getString("name");
            String strps=msg.getData().getString("password");
            MyMessage message=new MyMessage();
            message.setb((byte)1);
            message.setUsername(str);
            message.setPassword(strps);
            try {
                connect.sendBuffer.clear();
                connect.sendBuffer.put(message.Message2Byte());
                connect.sendBuffer.flip();
                connect.socketChannel.write(connect.sendBuffer);
            } catch (Exception e) {

                e.printStackTrace();
            }
        }
    }

}
服务器代码

package mytcp;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

public class NioServer {

    /**
     * @param args
     */
    private int port = 20001;
    final makeFlagFalse timerFlag = new makeFlagFalse();
    static makeFlagFalse loginLoopBoolean = new makeFlagFalse();
    private static ByteBuffer sBuffer = ByteBuffer.allocate(1024);
    private static ByteBuffer rBuffer = ByteBuffer.allocate(1024);
    private static Map<SocketChannel, Integer> clientsMap = new HashMap<SocketChannel, Integer>();
    private Selector selector = null;
    private ServerSocketChannel serverSocketChannel = null;
    private Object gate = new Object();

    public NioServer(int port) {
        this.port = port;
        try {
            init();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException, IOException {
        final NioServer server = new NioServer(20001);
        Thread accept = new Thread() {
            public void run() {
                server.accept();
            }
        };

        accept.start();
        while (loginLoopBoolean.flag == true) 
            server.loginService();
        server.gamePlay(clientsMap);
    }

    public void init() throws IOException {
        selector = Selector.open();
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().setReuseAddress(true);
        // serverSocketChannel.configureBlocking(false);
        serverSocketChannel.socket().bind(new InetSocketAddress(port));
        System.out.println("服务器启动");
    }

    public void accept() {
        while (true) {
            try {
                SocketChannel socketChannel = serverSocketChannel.accept();
                System.out.println("receive the connection from "
                        + socketChannel.socket().getInetAddress() + ":"
                        + socketChannel.socket().getPort());

                socketChannel.configureBlocking(false);
                synchronized (gate) {
                    selector.wakeup();
                    socketChannel.register(selector, SelectionKey.OP_READ);
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
                System.out.println("Damn it");
            }
        }
    }

    public void loginService() throws InterruptedException {


            synchronized (gate) {
            }
            try {
                int n = selector.select();
                if (n == 0){}
                else{
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                for (SelectionKey key : selectionKeys) {
                    try {
                        if (key.isReadable()) {
                            handle_receive_login(key);
                        }
                    } catch (Exception e) {
                        try {
                            if (key != null) {
                                key.cancel();
                                key.channel().close();
                            }
                        } catch (Exception ex) {
                            e.printStackTrace();
                        }
                    }
                }
                selectionKeys.clear();
              }
            } catch (Exception e) {
                e.printStackTrace();
            }

    }

    public void handle_receive_login(SelectionKey key) {
        SocketChannel socketChannel = null;
        ServerMessage message = null;
        ServerMessage sendMessage = new ServerMessage();
        socketChannel = (SocketChannel) key.channel();
        rBuffer.clear();
        try {
            int count = socketChannel.read(rBuffer);
            if (count > 0) {
                rBuffer.flip();
                message = ServerMessage.byte2Message(rBuffer.array());
                System.out.println("Receive from"+ socketChannel.socket().getInetAddress() + " : "+ message.getb());
                switch(message.getb()){
                case(1):
                        int valid = DB.idCheck(message.getUsername(),
                                message.getPassword());
                        sendMessage.setb((byte) 2);
                        sendMessage.setValid(valid);
                        sendMes sendMes = new sendMes(sendMessage, socketChannel);
                        sendMes.send();

                    break;
                case(2):
                    break;
                case (3):
                    if(timerFlag.flag){
                        if(message.getReady() == 1){
                            if(clientsMap.size() < 6){
                                clientsMap.put(socketChannel, clientsMap.size() + 1);
                                sendMessage.setb((byte) 3);
                                sendMessage.setReady(1);
                                sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
                                sendMes1.send();
                            }

                            else{
                                sendMessage.setb((byte) 3);
                                sendMessage.setReady(0);
                                sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
                                sendMes1.send();
                            }

                            Timer timer = new Timer();

                            System.out.println("flag is " + timerFlag.flag);
                            TimerTask task = new TimerTask(){
                                public void run(){
                                    timerFlag.falsify();
                                    System.out.println("flag now is " + timerFlag.flag);
                                }
                            };
                            timer.schedule(task, 20*1000);
                        }
                    }else{
                        sendMessage.setb((byte) -1); /*-1 implies that game is currently in progress*/
                        sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
                        sendMes1.send();
                    }
                    break;

                case (4):
                    if(timerFlag.flag == true){
                        sendMessage.setb((byte) -2); /*send message saying "waiting for other players*/
                        sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
                        sendMes1.send();
                    }else{
                        loginLoopBoolean.falsify();
                    }
                    break;
                }   
            }/*end of if(count=0)*/
        } catch (Exception e) {
            e.printStackTrace();
            key.cancel();
            try {
                socketChannel.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

    }


    public void gamePlay(Map<SocketChannel, Integer> clientsMap) throws IOException, InterruptedException{
        Dealer dealer = new Dealer();
        dealer.createDeck();
        ServerMessage sendMessage = new ServerMessage();

        if(!clientsMap.isEmpty()){  
            Set<SocketChannel> clientSet = clientsMap.keySet();
            Iterator<SocketChannel> iterator=clientSet.iterator();
            SocketChannel currentPlayer;
            while(iterator.hasNext()){
                currentPlayer=iterator.next();  
                sendMessage.setb((byte) 4);
                sendMessage.setCard1(dealer.dealCard(dealer.deck));
                sendMessage.setCard2(dealer.dealCard(dealer.deck));
                sendMes sendMes1 = new sendMes(sendMessage, currentPlayer);
                sendMes1.send();
            }
            //send who's turn it is 
            loginService();
        }
    }

    public static class makeFlagFalse{
        boolean flag;
        public makeFlagFalse() {
            this.flag = true;
        }
        public void falsify(){
            flag = false;
        }
        public void makeTrue(){
            flag = true;
        }
    }

    public class sendMes{
        ServerMessage message;
        SocketChannel currentPlayer;

        sendMes(ServerMessage message,SocketChannel currentPlayer){
            this.message = message;
            this.currentPlayer=currentPlayer;
        }
        public void send() throws IOException{
            sBuffer.clear();
            sBuffer.put(message.Message2Byte());
            sBuffer.flip();
            currentPlayer.write(sBuffer);
        }
    }


}
包mytcp;
导入java.io.IOException;
导入java.net.InetSocketAddress;
导入java.nio.ByteBuffer;
导入java.nio.channels.SelectionKey;
导入java.nio.channels.Selector;
导入java.nio.channels.ServerSocketChannel;
导入java.nio.channels.SocketChannel;
导入java.util.HashMap;
导入java.util.Iterator;
导入java.util.Map;
导入java.util.Set;
导入java.util.Timer;
导入java.util.TimerTask;
公共类NioServer{
/**
*@param args
*/
专用int端口=20001;
final makeFlagFalse timerFlag=new makeFlagFalse();
静态makeFlagFalse loginLoopBoolean=new makeFlagFalse();
私有静态ByteBuffer sBuffer=ByteBuffer.allocate(1024);
私有静态ByteBuffer rBuffer=ByteBuffer.allocate(1024);
私有静态映射clientsMap=newhashmap();
私有选择器=null;
私有服务器socketchannel服务器socketchannel=null;
私有对象门=新对象();
公共NioServer(int端口){
this.port=端口;
试一试{
init();
}捕获(例外e){
e、 printStackTrace();
}
}
公共静态void main(字符串[]args)引发InterruptedException、IOException{
最终NioServer=新NioServer(20001);
线程接受=新线程(){
公开募捐{
accept();
}
};
accept.start();
while(loginLoopBoolean.flag==true)
server.loginService();
服务器。游戏性(clientsMap);
}
public void init()引发IOException{
选择器=selector.open();
serverSocketChannel=serverSocketChannel.open();
serverSocketChannel.socket().setReuseAddress(true);
//serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(新的InetSocketAddress(端口));
System.out.println(“服务器启动");
}
公开无效接受(){
while(true){
试一试{
SocketChannel SocketChannel=serverSocketChannel.accept();
System.out.println(“从接收连接”
+socketChannel.socket().getInetAddress()+“:”
+socketChannel.socket().getPort());
socketChannel.configureBlocking(假);
同步(门){
selector.wakeup();
socketChannel.寄存器(选择器,SelectionKey.OP_READ);
}
}捕获(例外e){
e、 printStackTrace();
System.out.println(e.getMessage());
System.out.println(“该死的”);
}
}
}
public void loginService()引发InterruptedException{
同步(门){
}
试一试{
int n=选择器。选择();
如果(n==0){}
否则{
设置selectionKeys=selector.selectedKeys();
用于(选择键:选择键){
试一试{
if(key.isReadable()){
处理接收登录(密钥);
}
}捕获(例外e){
试一试{
if(key!=null){
键。取消();
key.channel().close();
}
}捕获(例外情况除外){
e、 printStackTrace();
}
}
}
selectionKeys.clear();
}
}捕获(例外e){
e、 printStackTrace();
}
}
公共无效句柄\u接收\u登录(SelectionKey){
SocketChannel SocketChannel=null;
ServerMessage=null;
ServerMessage sendMessage=新建ServerMessage();
socketChannel=(socketChannel)key.channel();
rBuffer.clear();
试一试{

int count=socketChannel.read(rBuffer); 如果(计数>0){ rBuffer.flip(); message=ServerMessage.byte2Message(rBuffer.array()); System.out.println(“接收自”+socketChannel.socket().getInetAddress()+”:“+message.getb()); 开关(message.getb()){ 案例(1): int valid=DB.idCheck(message.getUsername(), message.getPassword()); setb((字节)2); sendMessage.setValid(有效); sendMes sendMes=新的sendMes(sendMessage,socketChannel); sendMes.send(); 打破 案例(2): 打破 案例(3): if(timerFlag.flag){ if(message.getReady()==1){ if(clientsMap.size()<6){ 客户映射放置(s)
private Object gate = new Object();