我有一个用Java编码的客户端和服务器,一旦服务器收到来自客户端的一条消息,服务器就会停止接收所有新消息。当客户端尝试发送更多消息时,不会引发任何错误。我似乎无法找出为什么它不允许或接收新连接!请帮忙。
public class Server implements Runnable {
@Override
public void run() {
ServerSocket echoServer = null;
String line;
DataInputStream is;
PrintStream os;
Socket clientSocket = null;
boolean Listening = true;
int sPort = 9999;
// Try to open a server socket on port 9999
try {
echoServer = new ServerSocket(sPort);
}
catch (IOException e) {
System.out.println(e);
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams
while (Listening){
try {
clientSocket = echoServer.accept();
is = new DataInputStream(clientSocket.getInputStream());
//os = new PrintStream(clientSocket.getOutputStream());
// As long as we receive data, echo that data back to the client.
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
答案 0 :(得分:0)
while (true)
{
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
接受连接后,它进入这个无限循环。这个循环它永远不会接受新的连接。
解决这个问题,每当新客户端到来时启动新线程,传递客户端的套接字连接并从该客户端读取数据。
答案 1 :(得分:0)
我看到两个问题如下:
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
无论您是在不同的线程中阅读还是在同一线程中读取内容,都需要在读取Socket中的内容后中断。
您需要将boolean Listening
声明为volatile
,否则服务器将无法停止。
答案 2 :(得分:0)
while(true){ line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
代码将阻止新请求,因此不会接受第二个请求。 我举一个例子来说明你的代码。希望对你有所帮助。 服务器类将仅被用户接受套接字连接并创建一个新线程来处理它。
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server implements Runnable {
@Override
public void run() {
ServerSocket echoServer = null;
boolean listening = true;
Socket clientSocket = null;
int sPort = 9999;
// Try to open a server socket on port 9999
try {
echoServer = new ServerSocket(sPort);
} catch (IOException e) {
System.out.println(e);
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams
while (listening) {
try {
clientSocket = echoServer.accept();
System.out.println("receive new connection");
new ProcessClientThread(clientSocket).start();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}
}
ProcessClientThread类扩展了Thread Class并使用Socket类型参数定义了一个构造函数。覆盖它的run方法。 run方法从socket获取输入流并将其打印出来。当它接受0时,它将关闭scoket连接。它的代码就像这样
import java.io.DataInputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
public class ProcessClientThread extends Thread {
Socket socket = null;
public ProcessClientThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
DataInputStream is;
String line;
boolean flag = true;
try {
is = new DataInputStream(socket.getInputStream());
while (flag) {
line = is.readLine();
if (Integer.valueOf(line) != 0) {
// os.println(line);
// Logger.getLogger(Level.SEVERE,
// "New connection to server {0}", line);
System.out.println(line);
} else {
Writer w = new OutputStreamWriter(socket.getOutputStream());
w.write(0);
w.flush();
flag = false;
socket.close();
System.out.println("close a connection");
}
}
} catch(Exception e) {
}
}
}
有一个用于启动服务器线程的StartUp类。
public class StartUp {
public static void main(String[] args) {
new Thread(new Server()).start();
}
}
运行以下客户端类以测试服务器。
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Exception {
Socket client = new Socket("localhost", 9999);
OutputStreamWriter writer = new OutputStreamWriter(client.getOutputStream());
Reader reader = new InputStreamReader(System.in);
Reader serverReader = new InputStreamReader(client.getInputStream());
boolean flag = true;
while(flag) {
int readContent = reader.read();
writer.write(readContent);
writer.flush();
if(readContent == 0) {
writer.close();
client.close();
flag = false;
}
}
}
}