扫描仪hasNext(),但无法用nextLine()读取

时间:2014-07-13 01:02:56

标签: java sockets java.util.scanner

我正在尝试制作一个多线程服务器(因此可以被更多用户同时访问)。我设法在用户和服务器之间建立连接,.isConnected()返回true,hasNext()返回true,但程序停在.nextLine()。为什么? 服务器的第一部分:

import java.awt.Dimension;
import java.io.*;
import java.net.*;
import java.util.*;

import javax.swing.JFrame;
import javax.swing.JTextField;
public class Testserver {
    static int nr=0,i;
    String mass;
    boolean ok;
    public static ArrayList<Socket> Connection=new ArrayList<Socket>();
    public static ArrayList<String> Users=new ArrayList<String>();
    public static ArrayList<Thread> Tests=new ArrayList<Thread>();
    public static JTextField user;
    public static void main(String[] args) throws Exception{
        JFrame f=new JFrame();
        user=new JTextField("",20);
        Dimension us=user.getPreferredSize();
        user.setBounds(500,350,us.width,us.height);
        f.setTitle("Testserver");
        f.setSize(1200,820);
        f.setLocationRelativeTo(null);
        f.setResizable(false);
        f.setVisible(true);
        f.setLayout(null);
        f.add(user);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        try{
            ServerSocket Srv=new ServerSocket(201);
            while(true){
                Socket Sock=Srv.accept();
                nr=Connection.size();
                if(nr<20){
                    Connection.add(Sock);
                    Tests.add(new Thread(new Testserver_run(Sock,nr)));
                    Tests.get(nr).start();
                }
                else{
                    PrintStream ps=new PrintStream(Sock.getOutputStream());
                    ps.println("server full");
                    ps.flush();
                }
            }
        } catch(Exception e){
        }
    }
}

第二部分:

import java.io.*;
import java.net.*;
import java.util.*;
public class Testserver_run implements Runnable{
    Socket Sock;
    Scanner in;
    PrintWriter out;
    String mass="9";
    int nr=Testserver.nr,id;
    public Testserver_run(Socket S,int idd){
        this.Sock=S;
        this.id=idd;
    }
    public boolean checkconnection() throws IOException{
        Testserver.user.setText("6");
        if(!Sock.isConnected()){
            Testserver.user.setText("7");
            Testserver.Connection.remove(id);
            Testserver.Users.remove(id);
            Testserver.Tests.remove(id);
            return false;
        }
        else return true;
    }
    public void run(){
        Testserver.user.setText("1");
        try{
            in=new Scanner(Sock.getInputStream());
            out=new PrintWriter(Sock.getOutputStream());
            Testserver.user.setText("2");
            try{
                while(checkconnection()){
                    if(in.hasNext()){
                        Testserver.user.setText("5");
                        mass=in.nextLine();
                        Testserver.user.setText(mass);
                    }
                }
            }
            finally{
                Testserver.user.setText("3");
                Sock.close();
            }
        } catch(Exception e){

        }
    }
}

客户端部分:

import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.Scanner;
import java.awt.Dimension;
import java.awt.event.*;
public class Testuser{
    public static JTextField user;
    public static Socket S;
    public static PrintWriter out;
    public static Scanner in;
    public static String mess;
    public static void main(String[] args)  throws Exception{
//      Testuser Test=new Testuser();
        user=new JTextField("",20);
        Dimension us=user.getPreferredSize();
        user.setBounds(500,350,us.width,us.height);
        user.addKeyListener(new Al1());
        JFrame f=new JFrame();
        f.setTitle("Test");
        f.setSize(1200,820);
        f.setLocationRelativeTo(null);
        f.setResizable(false);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(null);
        f.add(user);
        f.setFocusable(true);
        try {
            S=new Socket("localhost",201);
            out = new PrintWriter(S.getOutputStream(), true);
            in = new Scanner(
                    new InputStreamReader(S.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know localhost");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Cannot open IO");
            System.exit(1);
        }
    }
    public static void send(String mess,PrintWriter out) {
        out.write(mess);
        out.flush();
    }
    public static class Al1 extends KeyAdapter{
        int key;
        public void keyPressed(KeyEvent e){
            key=e.getKeyCode();
            if(key==KeyEvent.VK_ENTER){
                    mess = user.getText();
                    if(mess.equals("stop")){
                        try{
                            S.close();
                        }catch(Exception exc){

                        }
                    }else{
                        send(mess,out);
                    }
                }
            }
    }
}

提前致谢!

1 个答案:

答案 0 :(得分:1)

  

.isConnected()返回true,hasNext()返回true,但程序停在.nextLine()。为什么?

对于开始isConnected(),仅表示套接字在过去的某个时刻已连接。它不会告诉您连接仍然是否可行。

hasNext()返回truenextLine()块的一种情况是有待读取的字符,但尚未读取“行尾”标记。 hasNext()结果告诉您next()将为您提供令牌。它不会告诉您nextLine()是否会成功。如果你想知道这一点,请拨打hasNextLine() ...但要注意 也会阻止等待一条线路。

所以,为了解决当前的问题,我无法看到你在哪里写行尾标记。在客户端。实际上,我看不出你在哪里明确地写了任何形式的令牌间东西。如果您要使用Scanner,则需要仔细阅读javadocs 并设计“协议”以匹配该类的功能。