当前位置: 首页 > 知识库问答 >
问题:

Java套接字-客户端不从服务器的套接字读取字符串

裴欣荣
2023-03-14

我有两个通过字符串与套接字通信的Java项目。一个是客户端,另一个是服务器。服务器通过“ServerSocket”接受连接,并使用新创建的“套接字”创建新的“会话”(线程)。

同时,客户端只有一个“套接字”,一旦连接了这个套接字,客户端就会创建一个“ClientSession”(线程,非常类似于“session”)。

我想要的是服务器通过“username”字符串询问客户机他的用户名,客户机用他的用户名回答。但答案再也回不来了。我认为可能是BufferedReader和PrintWriter行在错误的地方触发的同步问题。

---------服务器代码--------------

登录类:

public class Login implements Runnable {

private ArrayList<Session> sessions;
private int port;
private Thread thread;
private ServerSocket serverSocket;
private Game game;

public Login(int port, Game game) throws Exception {
    this.sessions = new ArrayList();
    this.port = port;
    this.serverSocket = new ServerSocket(port);
    this.game = game;
    this.thread = new Thread(this);
    this.thread.start();
}

@Override
public void run() {
    while(true) {
        Socket socket;
        try {
            System.out.println("[Server Network] Waiting for a new player to log in.");
            socket = serverSocket.accept();
            sessions.add(new Session(socket,this));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

public void addPlayer(Player p) {
    this.game.addPlayer(p);
}

}

会话类:

public class Session implements Runnable {

private String username;
private Thread thread;
private Socket socket;
private BufferedReader br;
private OutputStreamWriter os;
private PrintWriter out;
private Login login;

private boolean ready;

public Session(Socket socket, Login login) throws IOException {
    this.login = login;
    this.socket = socket;
    this.ready = false;

    this.br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    this.os = new OutputStreamWriter(socket.getOutputStream());
    this.out = new PrintWriter(os);

    System.out.println("[Server network] Session created for client with ip: "+socket.getInetAddress().getHostAddress());

    this.thread = new Thread(this);
    this.thread.start();
}

public void send(String m) {
    System.out.println("[Server network] Sending message: "+m);
    out.write(m);
    out.flush();
    System.out.println("[Server network] Message sent: "+m);
}


@Override
public void run() {
    while (true) {
        if (!ready) {
            try {
                this.send("USERNAME");
                this.username = br.readLine();
                this.ready = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            String request = br.readLine();
            System.out.println(request);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

}

---------客户端代码------------

游戏类:

public class Game {

private Window window;

private LocalPlayer localPlayer;
private ArrayList<Player> players;
private Map map;

private String username;

private String serverIpAddress;
private ClientSession clientSession;
private static int port = 23123;

public Game(Window window, Map map) throws UnknownHostException, IOException {
    System.out.println("Game Launched.");

    //Asks for the server ip address and creates a session.
    //this.serverIpAddress = JOptionPane.showInputDialog(null,"Please enter the server ip address.",JOptionPane.QUESTION_MESSAGE);
    this.serverIpAddress = "localhost";

    //this.username = JOptionPane.showInputDialog(null,"What is your username?",JOptionPane.QUESTION_MESSAGE);
    this.username = "GriffinBabe";

    this.clientSession = new ClientSession(new Socket(serverIpAddress,port),this);

    this.window = window;
    this.localPlayer = new LocalPlayer(new Warrior(),this.username,'R');
    this.map = map;

}

public LocalPlayer getLocalPlayer() {
    return this.localPlayer;
}

public Map getMap() {
    return map;
}

}

ClientSession类:

public class ClientSession implements Runnable {

private Socket socket;
private Thread thread;
private BufferedReader br;
private OutputStreamWriter os;
private PrintWriter out;
private Game game;

public ClientSession(Socket socket, Game game) throws IOException {
    this.game = game;
    this.socket = socket;

    this.br = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
    this.os = new OutputStreamWriter(this.socket.getOutputStream());
    this.out = new PrintWriter(os);

    System.out.println("[Client network] Session created for server with ip: "+socket.getInetAddress().getHostAddress());

    this.thread = new Thread(this);
    this.thread.start();
}

public void send(String m) {
    System.out.println("[Client network] Sending message: "+m);
    out.write(m);
    out.flush();
    System.out.println("[Client network] Message sent: "+m);
}

@Override
public void run() {
    while(true) {
        try {
            String request = br.readLine();
            System.out.println(request);
            switch (request) {
            case "USERNAME":
                send(game.getLocalPlayer().getUsername());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

}

以下是控制台日志:

服务器(当然是先启动的):

客户:

共有2个答案

谭裕
2023-03-14

在发送方法中,尝试将out.write(m)更改为out.println(m)

readline()方法将保持读取,直到它命中行终止符或流的结尾(以先到者为准)。println()方法将自动在试图发送的字符串末尾放置行终止符。

https://docs.oracle.com/javase/7/docs/api/java/io/printwriter.html#println()

诸葛品
2023-03-14

您的服务器发送“username”,然后等待。客户端读取下一行,然后阻塞,直到接收到它为止。因为服务器从不发送EOL字符,所以您会出现死锁。如果客户端读取一行,服务器应该发送一行。

 类似资料:
  • 我试图用java实现一个客户端服务器,在这里我读取客户端中的输入并在服务器中执行UperCase,然后返回客户端并打印UperCase。我使用ObjectOutputStream和ObjectInputStream进行读写,但是当我在客户机中键入一个msg时,程序会显示以下错误: Digite uma msg casa java.io.eofexception位于java.io.datainput

  • 首先我要感谢你花时间... 我在macbook中用C++创建了一个服务器套接字,在运行windows XP的不同机器中用Java创建了一个客户机/套接字。我已将端口指定为5000,但无法指定正确的主机,因此无法进行连接。当我在windows xp中使用WinSock2创建一个C++服务器/套接字时,当我使用本地主机时,连接是完美的...有什么想法吗??? 提前Thnx int main(int a

  • 问题内容: 我试图用没有gui的服务器连接带有gui的客户端。连接已完成,但我看不到这两个应用程序之间的任何消息。(我应该在客户端中找到SERVER HERE,在服务器中找到CLIENT HERE) 客户端连接代码: (输入和输出在此客户端类扩展到的GUI类中定义。定义为“受保护的BufferedReader输入;受保护的PrintWriter输出;”) 另外,服务器代码: 连接似乎还可以,所以我

  • 我组装了一个Java套接字服务器和客户端,可以互相发送消息,我想使用JavaScript作为客户端,但是。。。下面是在托管Java服务器并加载JavaScript客户端时发生的情况。 JavaScript: 这将在chrome控制台中打印: 到“ws://127.0.0.1:9005/”的WebSocket连接失败:WebSocket握手期间出错:无效状态行 WebSocket错误[对象事件] 我

  • 我正在尝试连接一个带有gui的客户端和一个没有gui的服务器。连接正在进行中,但我看不到这两个应用程序之间的任何消息。(我应该将服务器放在客户端中,而将客户端放在服务器中) 客户端连接代码: PS:我也在服务器中尝试了PrintWriter,也尝试了try catch in stream语句,问题仍然存在。

  • 我正试图从套接字服务器(Java)向套接字客户端(Python)发送一个映像,但客户端中接收到的映像大小不正确,无法打开。我不知道我做错了什么。有什么建议吗?