客户端/服务器应用程序
伙计们有谁能告诉我我在这里做什么错了?下面是四个文件Client,main,Server,main。尝试从Server.readLine()尝试完成后,客户端发生错误。
错误:在客户端软件错误造成连接中止:recv的失败客户端/服务器应用程序
package client;
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Client
{
private PrintWriter toServer;
private BufferedReader fromServer;
private Socket socket;
public Client()throws IOException
{
socket = new Socket("127.0.0.1",3000);
}
public void openStreams() throws IOException
{
//
// InputStream is = socket.getInputStream();
// OutputStream os = socket.getOutputStream();
// fromServer = new BufferedReader(new InputStreamReader(is));
// toServer = new PrintWriter(os, true);
toServer = new PrintWriter(socket.getOutputStream(),true);
fromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
public void closeStreams() throws IOException
{
fromServer.close();
toServer.close();
socket.close();
}
public void run()throws IOException
{
openStreams();
String msg = "";
Scanner scanner = new Scanner(System.in);
toServer.println("Hello from Client.");
// msg = scanner.nextLine();
while (msg != "exit")
{
System.out.println(">");
// msg = scanner.nextLine();
toServer.println("msg");
String tmp = fromServer.readLine();
System.out.println("Server said: " + tmp);
}
closeStreams();
}
}
package server;
import java.net.*;
import java.io.*;
public class Server
{
private ServerSocket serverSocket;
private Socket socket;
private PrintWriter toClient;
private BufferedReader fromClient;
public void run() throws IOException
{
System.out.println("Server is waiting for connections...");
while (true)
{
openStreams();
processClient();
closeStreams();
}
}
public void openStreams() throws IOException
{
serverSocket = new ServerSocket(3000);
socket = serverSocket.accept();
toClient = new PrintWriter(socket.getOutputStream(),true);
fromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
public void closeStreams() throws IOException
{
fromClient.close();
toClient.close();
socket.close();
serverSocket.close();
}
public void processClient()throws IOException
{
System.out.println("Connection established.");
String msg = fromClient.readLine();
toClient.println("Client said " + msg);
}
}
package client;
import java.io.IOException;
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try
{
Client client = new Client();
client.run();
}
catch(IOException e)
{
System.err.println("Error in Client " + e.getMessage());
}
}
}
package server;
import java.io.IOException;
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Server server = new Server();
try
{
server.run();
}
catch(IOException e)
{
System.err.println("Error in Server " + e.getMessage());
}
}
}
你的服务器端的所有混合起来。您需要另一个类,称为Connection或ConnectedClient,它实现了Runnable;将Socket作为构造函数参数;并为特定客户端执行所有服务器端I/O。目前你已经将这一切与你的服务器类混淆了。所有你的服务器类应该做的就是创建一个ServerSocket,并进入一个循环,接受Sockets并创建Connection对象并为它们启动线程。 Server的run()方法中的Socket对象只是一个本地对象,并且相关的输入/输出流或读写器属于Connection类,而不属于Server类。
这样,您可以同时处理多个客户端,而不需要彼此踩到彼此的脚趾。
您的下一个问题是,readLine()在另一端关闭连接时返回null。每次调用readLine()时,必须在进行任何其他处理之前测试此的第一个。
接下来,如果在使用Socket时发生SocketException或IOException以外的SocketException或IOException,那么它将死亡 - 关闭它,忘记该客户端并退出线程(如果它发生在服务器中)。
发布的代码在客户端的无限循环中运行。 猜测取消注释(以Client.java最后scanner.nextLine()
)这行之后,我发现了以下问题:
- 客户端保持连接打开,但在接收到第一消息后,服务器关闭。
- 谓语
msg != "exit"
始终是真实的在Java中 - 使用String.equals()
的工作Server.processClient是:
public void processClient()throws IOException
{
String msg = null;
do {
msg = fromClient.readLine();
toClient.println("Client said " + msg);
} while (!"exit".equals(msg));
}
的工作Client.run是:
public void run()throws IOException
{
openStreams();
String msg = "";
Scanner scanner = new Scanner(System.in);
while (!"exit".equals(msg))
{
System.out.print(">");
msg = scanner.nextLine();
toServer.println(msg);
String tmp = fromServer.readLine();
System.out.println("Server said: " + tmp);
}
closeStreams();
}
+评论:我专注于纠正明显的错误。 EJP的答案为您提供了很好的指导方法,使您的代码更好,包括处理同时连接,正确使用线程等。
您打算告诉我们错误是什么,或者我们猜测? – skaffman 2010-06-09 07:40:15
@skaffman对不起,我忘了它。我已更新我的原始帖子 。 – 2010-06-09 07:48:46
@EJP和Miklos谢谢你们的回答。 – 2010-06-09 13:46:30