Java套接字服务器没有响应
出于好奇,我开始使用java套接字 我写了一小段代码,一个服务器和一个客户端 服务器接受字符串并将其转换为大写,然后返回给客户端 我希望服务器能够处理多个客户端,并具有持久连接 以下是服务器代码:Java套接字服务器没有响应,java,eclipse,sockets,Java,Eclipse,Sockets,出于好奇,我开始使用java套接字 我写了一小段代码,一个服务器和一个客户端 服务器接受字符串并将其转换为大写,然后返回给客户端 我希望服务器能够处理多个客户端,并具有持久连接 以下是服务器代码: package server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.n
package server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
public class Server {
private ServerSocket listener;
private ArrayList<Socket> clients;
public Server() throws IOException{
clients = new ArrayList<Socket>();
listener = new ServerSocket(7575);
}
public Server(int port) throws IOException{
clients = new ArrayList<Socket>();
listener = new ServerSocket(port);
}
public void start() throws IOException, InterruptedException{
Thread one = new Thread(){
public void run(){
while (true){
Socket socket = null;
try {
socket = listener.accept();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (socket.isConnected()){
try {
socket.setKeepAlive(true);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clients.add(socket);
System.out.println(socket.getRemoteSocketAddress().toString());
}
}
}
};
Thread two = new Thread(){
public void run(){
try {
while (true){
work();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
one.start();
two.start();
one.join();
two.join();
stop();
}
private void stop() throws IOException{
listener.close();
}
private void work() throws IOException{
if (clients.size() == 0){
return;
}
for(int i = 0; i < clients.size(); i++){
Socket socket = clients.get(i);
if (!socket.isClosed()){
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String data = br.readLine();
if (data == null) continue;
out.println(data.toUpperCase());
}
else{
clients.remove(socket);
}
}
}
}
package entry;
import java.io.IOException;
import server.Server;
public class Main {
public static void main(String args[]) throws IOException{
Server server = new Server();
try {
server.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
奇怪的是,当我在服务器代码中设置断点并在eclipse中逐步执行代码时,代码完全按照预期工作,即我在客户机中得到响应
但是,当我在eclipse中直接运行它时,我在客户机中没有得到响应
我无法理解出了什么问题
编辑
我似乎已经解决了这个问题
以下是代码片段:
Thread two = new Thread(){
public void run(){
try {
while (true){
Thread.sleep(1000); //This is the added line
work();
}
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
但我仍然不清楚是什么造成了时间上的差异。
有没有更干净的方法来实现这一点?我用另一种方法解决了这个问题 以下是新方法: ServerHandler.java:
package server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
public class ServerHandler extends Thread{
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private ArrayList<Socket> clients;
public ServerHandler(Socket socket) throws IOException{
this.socket = socket;
clients = new ArrayList<Socket>();
if (!clients.contains(socket)){
clients.add(this.socket);
System.out.println(this.socket.getRemoteSocketAddress());
}
}
@Override
public void run(){
while (true){
if (clients.isEmpty()) break;
String str = null;
for (int i = 0; i < clients.size(); i++){
Socket socket = clients.get(i);
if (socket.isClosed()){
clients.remove(socket);
continue;
}
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
str = in.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.println(str.toUpperCase());
}
}
}
}
好了,我们开始吧。我不明白如何使用
Arraylist
来维护连接,除非您正在处理每个客户端的混乱细节
一次处理多个客户端的最常用或首选方法可以通过一个示例来理解:
Server.java
如您所见,我刚刚定义了一个类,该类将侦听客户端连接,一旦向服务器发出请求,它将启动下一个类中定义的线程。这里需要注意的一点是使用Try with Resources
块。任何实现Closeable
接口的类都可以包含在此try语句中。try with resources自动为我处理流或连接的关闭。这意味着,从代码中删除所有冗余的try-catch
块,并改用此try
现在,
ServerThread.java
观察这里的try with resources
语句,我们可以在这里初始化多个连接/输入输出流,一旦编译器从try
语句返回,所有打开的连接都将自动关闭。另外,观察while
语句,它将一直运行,直到客户端发送消息为止,如果消息是“再见”
,它将退出
最后是一个向服务器发送请求的客户端程序
Client.java
请注意,此处的语句将在用户输入消息之前循环,如果消息为“bye”,它将退出。从上面的解释可以很容易理解程序的其余部分。服务器中的main
方法在哪里?添加了main方法。只是没有添加到这里。如果我没有错的话,您正在尝试实现多个客户端连接到服务器?如果是这样,那么肯定有更好的方法来实现这一点是的,我正试图做到这一点。我修改了我的代码,以使用这种方法完成它。你能告诉我你说的其他更好的方法吗。我使用了完全相同的方法。请参阅下面的代码。我使用ArrayList的原因是,我计划编写一个简单的聊天服务器。因此,我需要维护客户机列表,以便可以从一个客户机向另一个客户机发送消息。如果有更优雅的方式,请让我知道!:)此方法是由Ora开发人员
提出的,因为它高效地使用线程概念,并利用线程
和尝试资源
的功能,以最小化所涉及的复杂性。代码中唯一的问题是,很难读取和使用冗余的try-catch
语句。剩下的我想不出任何其他问题:)一定要投票,接受答案,如果你得到了答案,就关闭线程。
package server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
public class ServerHandler extends Thread{
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private ArrayList<Socket> clients;
public ServerHandler(Socket socket) throws IOException{
this.socket = socket;
clients = new ArrayList<Socket>();
if (!clients.contains(socket)){
clients.add(this.socket);
System.out.println(this.socket.getRemoteSocketAddress());
}
}
@Override
public void run(){
while (true){
if (clients.isEmpty()) break;
String str = null;
for (int i = 0; i < clients.size(); i++){
Socket socket = clients.get(i);
if (socket.isClosed()){
clients.remove(socket);
continue;
}
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
str = in.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.println(str.toUpperCase());
}
}
}
}
package entry;
import java.io.IOException;
import java.net.ServerSocket;
import server.ServerHandler;
public class Main {
public static void main(String args[]) throws IOException{
ServerSocket listener = new ServerSocket(7575);
try{
while (true){
new ServerHandler(listener.accept()).start();
}
}
catch(Exception e){
e.printStackTrace();
}
finally{
listener.close();
}
}
}
import java.net.ServerSocket;
import java.io.IOException;
class Server {
public static void main(String[] args) throws IOException {
try( ServerSocket ss = new ServerSocket(3333)) { // try with resources
new ServerThread(ss.accept()).start();
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerThread extends Thread {
Socket s = null;
public ServerThread(Socket s) {
super("ServerThread");
this.s = s;
}
public void run() {
try( PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
BufferedReader stream = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedReader write = new BufferedReader(new InputStreamReader(System.in))) {
System.out.println("In Server");
String in, out;
while ((in = stream.readLine()) != null) {
System.out.println("Msg 4m client: " + in);
if(in.equals("bye"))
break;
out = write.readLine();
pw.println(out);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
import java.net.Socket;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
class Client {
public static void main(String[] args) {
try( Socket s = new Socket("localhost", 3333);
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
BufferedReader stream = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedReader write = new BufferedReader(new InputStreamReader(System.in)) ) {
System.out.println("In Client");
String in;
while ((in = write.readLine()) != null) {
pw.println(in);
if(in.equals("bye"))
break;
System.out.println("Msg 4m server: " + stream.readLine());
}
} catch(IOException e) {
System.err.println("Exception: " + e);
}
}
}