线程是反社交的
所以我有两个线程 - 一个服务器线程和一个客户端线程。我可以让服务器写入,但客户端永远不会读取它。这里是客户端、服务器以及服务器生成的用于处理客户端连接的线程。
客户端 - 连接到套接字并尝试与服务器进行乒乓操作。客户端希望服务器先与它对话!
public class ClientMain {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("localhost", 14285);
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
} catch(IOException e) {
Log.write("Error in client thread ");
Log.write(e);
}
while(true) {
System.out.println("About to read!! :-D");
String fromServer = in.readLine();
System.out.println("From server: " + fromServer);
out.println("PONG");
}
}
}
服务器 - 这是服务器的启动方法。它生成一个线程来监视 serverSocket,并根据需要生成客户端线程。是的,我意识到在这样的方法中定义一个类是一种不好的做法......如果很难阅读,我很抱歉。
public void start() {
this.running = true;
// probably could have done this better, but it gets the job done
class Start implements Runnable {
Server server;
Start(Server server) { this.server = server; }
public void run() {
while(server.running) {
try {
Socket socket = server.serverSocket.accept();
Log.write("Accepted socket");
new ClientThread(server,socket).start();
} catch (IOException e) { e.printStackTrace(); }
}
}
}
Thread start = new Thread(new Start(this));
start.start();
}
这是客户端线程 - 这也不是那么多。我从套接字获取流,并写入一些数据,直到不再有数据为止,然后从客户端获取一些数据。
public void run() {
Log.write("Running clientthread");
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
} catch(IOException e) {
running = false;
Log.write("Error in client thread " + getName());
Log.write(e);
}
while(running) {
try {
String message = messageQueue.poll();
while(message != null) {
out.println(message);
Log.write("wrote message: " + message);
message = messageQueue.poll();
}
String input = in.readLine();
System.out.println("From client: " + input);
server.handle(username,input,this);
}
catch(IOException e) {
Log.write("Error in client thread " + getName() + " username=" + username);
Log.write(e);
break;
}
}
}
现在,这是我在服务器端得到的输出:
Accepted socket
Running clientthread
wrote message: PING
这向我表明它正在获取连接并写出消息。 (为了清楚起见,当客户端线程实例化时,PING 会填充到消息队列中,这样总有一些话要对客户端说以开始对话。这就像害羞线程的破冰船,嗯?)它也向我表明它没有从客户端返回任何内容,因为在 in.readLine()
之后没有任何内容打印。
此外,客户端上的唯一输出是它将要读取的通知。那么怎么会缺少服务器正在写的内容呢?
任何想法表示赞赏!
谢谢!!
So I have two threads going - a Server thread and a Client thread. I can get the server to write, but it never gets read by the client. Here is the client, server, and the thread spawned by the server to handle the client connection.
Client - connect to the socket and try to ping-pong with the server. The client expects the server to talk to it first!
public class ClientMain {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("localhost", 14285);
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
} catch(IOException e) {
Log.write("Error in client thread ");
Log.write(e);
}
while(true) {
System.out.println("About to read!! :-D");
String fromServer = in.readLine();
System.out.println("From server: " + fromServer);
out.println("PONG");
}
}
}
Server - this is the start method of the server. It spawns a thread for watching the serverSocket, and spawning client threads as necessary. Yes I realize it's sort of a bad practice to define a class inside a method like that... and my apologies if it's hard to read.
public void start() {
this.running = true;
// probably could have done this better, but it gets the job done
class Start implements Runnable {
Server server;
Start(Server server) { this.server = server; }
public void run() {
while(server.running) {
try {
Socket socket = server.serverSocket.accept();
Log.write("Accepted socket");
new ClientThread(server,socket).start();
} catch (IOException e) { e.printStackTrace(); }
}
}
}
Thread start = new Thread(new Start(this));
start.start();
}
Here's the client thread - this isn't all that much either. I get my streams from the socket, and write some data until I don't have anymore, then get some data from the client.
public void run() {
Log.write("Running clientthread");
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
} catch(IOException e) {
running = false;
Log.write("Error in client thread " + getName());
Log.write(e);
}
while(running) {
try {
String message = messageQueue.poll();
while(message != null) {
out.println(message);
Log.write("wrote message: " + message);
message = messageQueue.poll();
}
String input = in.readLine();
System.out.println("From client: " + input);
server.handle(username,input,this);
}
catch(IOException e) {
Log.write("Error in client thread " + getName() + " username=" + username);
Log.write(e);
break;
}
}
}
Now here's what I'm getting for an output on the server side:
Accepted socket
Running clientthread
wrote message: PING
This indicates to me that it's getting the connection and writing the message out. (For clarity, a PING gets populated in the messageQueue when the client thread is instantiated, that way there's always something to say to the client to get the conversation started. It's like an icebreaker for shy threads, eh?) It also indicates to me that it is getting nothing from the client back, because nothing prints after the in.readLine()
Also, the only output on the client is the notification that it's about to read. So how can it be missing what the server is writing?
Any ideas are appreciated!
Thanks!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我猜测,尝试添加:
I am guessing, try to add:
每次要发送消息时添加
out.flush();
。在完成之前不要关闭流。
仅当您处理完流时才添加
out.close();
。Add an
out.flush();
everytime you want to send a message.DO NOT CLOSE the stream until you are done with it.
add an
out.close();
only when you are done with the stream.