我正在尝试制作一个多线程服务器(因此可以被更多用户同时访问)。我设法在用户和服务器之间建立连接,.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);
}
}
}
}
}
提前致谢!
答案 0 :(得分:1)
.isConnected()返回true,hasNext()返回true,但程序停在.nextLine()。为什么?
对于开始isConnected()
,仅表示套接字在过去的某个时刻已连接。它不会告诉您连接仍然是否可行。
hasNext()
返回true
但nextLine()
块的一种情况是有待读取的字符,但尚未读取“行尾”标记。 hasNext()
结果告诉您next()
将为您提供令牌。它不会告诉您nextLine()
是否会成功。如果你想知道这一点,请拨打hasNextLine()
...但要注意 也会阻止等待一条线路。
所以,为了解决当前的问题,我无法看到你在哪里写行尾标记。在客户端。实际上,我看不出你在哪里明确地写了任何形式的令牌间东西。如果您要使用Scanner
,则需要仔细阅读javadocs 并设计“协议”以匹配该类的功能。