[英]Connecting to a Server, sending a string and receiving an object - BufferedReader not 'ready'?
服务器:
public Server() {
gui = new GUI();
try {
socket = new ServerSocket(2000);
while (true) {
Socket client = socket.accept();
gui.append("Client accepted.");
if (inetAddrFound(client.getInetAddress().getHostName())) {
Thread thread = new Thread(new IncomingClient(client));
threads.put(client, thread);
thread.start();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public class IncomingClient implements Runnable {
BufferedReader reader;
Socket sock;
public IncomingClient(Socket socket) {
gui.append("Incoming socket class instantiated.");
try {
this.sock = socket;
InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(streamReader);
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
gui.append(s.toString());
}
}
}
@Override
public void run() {
String message;
try {
while (true) {
gui.append("Trying to see if reader.readLine == null");
if (!reader.ready()) {
System.out.println("Reader is not ready.");
continue;
}
if ((message = reader.readLine()) != null && !Thread.currentThread().isInterrupted()) {
System.out.println("Reader is not null.");
System.out.println("Message = " + message);
gui.append(message);
if (idFound(message)) {
ObjectOutputStream stream = (ObjectOutputStream) sock.getOutputStream();
stream.writeObject(spooker);
stream.close();
threads.get(sock).interrupt();
threads.remove(sock);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端:
private void connect() {
try {
socket = new Socket(decode(ADDR), Integer.parseInt(decode(PORT)));
ois = new ObjectInputStream(socket.getInputStream());
writer = new PrintWriter(socket.getOutputStream());
writer.println(String.valueOf(encode(getMotherboardSN())));
writer.flush;
writer.close;
} catch (Exception e) {
e.printStackTrace();
}
}
public class IncomingSpookerObject implements Runnable {
@Override
public void run() {
SpookerObject object;
try {
while ((object = (SpookerObject) ois.readObject()) != null && !Thread.currentThread().isInterrupted()) {
spooker = (SpookerObject) ois.readObject();
thread.interrupt();
System.out.println(spooker.getX());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
我的目的是连接到服务器,将用户cpu id(每台计算机的唯一标识符)发送到服务器(cpu id是字符串),服务器将读取cpu id,如果用户已注册(例如,如果他们的cpu id在数据库上),然后它将向他们发送一个对象(Spooker对象)。
Spooker对象是一个仅包含int x = 4的测试对象,以及一个返回x,getX()的方法。
我尝试执行此操作的原因是为了帮助防止软件泄漏。 将来,spokeer对象将包含启动客户端软件的信息(例如GUI大小,GUI标题,字符串值等)。 这将使软件在连接到服务器并检索回特定信息时更难以泄漏。
我希望我尽可能清楚。
阿奇
编辑-更新的服务器对象。
服务器输出-
客户接受。 实例化传入的套接字类。 尝试查看reader.readLine == null
读者尚未准备就绪。 读者尚未准备就绪。 读者尚未准备就绪。 读者尚未准备就绪。 读者尚未准备就绪。 读者尚未准备就绪。
它会连续打印出来-为什么读者从未准备好?
编辑; 添加:
writer.println writer.flush(); writer.close();
您没有发送带有客户端数据的CR,因此就服务器而言,尚没有完整的行可供读取。 尝试将writer.write()
更改为writer.println()
。
我设法弄清楚了。 我不得不使用object = ois.readObject(); 对象实例
不是ois.readObject instanceOf
等等
对不起,简短的回答,很忙。
服务器正在尝试读取永无止境的行。 在您的connect方法中,您应该关闭输出流。
更新
这是一个有效的例子。 实际上,不得关闭输出流,因为它将关闭底层套接字。
服务器:
public class Server {
private static final Logger LOG = Logger.getLogger(Server.class.getName());
public static void main(String[] args) {
int port = args.length > 0 ? Integer.parseInt(args[0]) : 2000;
try (ServerSocket socket = new ServerSocket(port)) {
while (true) {
Socket client = socket.accept();
System.out.println("Client accepted.");
Thread thread = new Thread(new IncomingClient(client));
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
static class IncomingClient implements Runnable {
private final Socket sock;
private final SpookerObject spooker = new SpookerObject();
public IncomingClient(Socket socket) {
System.out.println("Incoming socket class instantiated.");
this.sock = socket;
}
@Override
public void run() {
try (InputStream istream = sock.getInputStream();
Reader reader = new InputStreamReader(istream);
BufferedReader in = new BufferedReader(reader);
OutputStream ostream = sock.getOutputStream();
ObjectOutputStream out = new ObjectOutputStream(ostream)) {
String message = in.readLine();
if (message != null && idFound(message)) {
while (!Thread.currentThread().isInterrupted()
&& sock.isConnected()) {
System.out.println("Reader is not null.");
System.out.println("Message = " + message);
out.writeObject(spooker);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
sock.close();
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
}
private boolean idFound(String id) {
return "abcdef".equals(id);
}
}
}
客户:
public class Client implements Closeable {
private static final Logger LOG = Logger.getLogger(Client.class.getName());
private final Socket socket;
private final ObjectInputStream ois;
public static void main(String[] args) {
try {
InetAddress server = InetAddress.getByName(args[0]);
int port = Integer.parseInt(args[1]);
String cpuId = args[2];
try (Client client = new Client(server, port, cpuId)) {
for (int i = 0; i < 3; ++i) {
System.out.println(client.readSpooker());
}
}
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
public Client(InetAddress address, int port, String cpuId)
throws IOException {
boolean ok = false;
socket = new Socket(address, port);
try {
OutputStream stream = socket.getOutputStream();
Writer writer = new OutputStreamWriter(stream, "UTF-8");
PrintWriter out = new PrintWriter(writer);
out.println(cpuId);
out.flush();
ois = new ObjectInputStream(socket.getInputStream());
ok = true;
} finally {
if (!ok) {
socket.close();
}
}
}
@Override
public void close() throws IOException {
try {
if (ois != null) {
ois.close();
}
} finally {
socket.close();
}
}
public SpookerObject readSpooker() throws IOException {
try {
return (SpookerObject)ois.readObject();
} catch (ClassNotFoundException ex) {
LOG.log(Level.SEVERE, null, ex);
throw new IOException(ex.getMessage());
}
}
}
只需删除ready()
测试并continue
。 没有任何意义。 您只是自旋循环,直到至少一个字节可用于读取而没有阻塞,然后您很可能还是阻塞了readLine()
,因为它将阻塞直到可以读取整行为止。
您还需要确定是否要发送线或对象。 您不能通过同一个套接字来做这两个事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.