【发布时间】:2015-06-11 05:18:07
【问题描述】:
我有一个与this 类似的问题,但我知道当我要求阅读一行时,发件人应该发送一个行尾。
让我感到困惑的是,在调试中,它可以工作。可能是因为我在调试时跳过的顺序(直到现在我什至不知道这会有所作为),但我想更好地理解它。
我已经使用过线程,但不是很多。
这是我的服务器类:
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Server {
protected static List<Game> games = new ArrayList<>();
protected static List<ServerThread> players = new ArrayList<>();
public static void main(String[] args) throws Exception {
int serverPort = 8945;
Server server = new Server();
ServerSocket welcomeSocket = new ServerSocket(serverPort);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
ServerThread st = new ServerThread(server,connectionSocket);
st.start();
int gameId = 0;
if(players.size()>0 && players.size()%2==0){
gameId++;
players.get(0).outToClient.write("START " + gameId
+ " 123 456" +"\n");
players.get(0).outToClient.flush();
players.get(1).outToClient.write("START " + gameId
+ " 456 123" +"\n");
players.get(1).outToClient.flush();
}
}
}
}
线程(基于this)
import java.io.*;
import java.net.Socket;
public class ServerThread extends Thread {
protected Server server;
protected Socket socket;
protected String playerName;
protected BufferedReader inFromClient;
protected BufferedWriter outToClient;
public ServerThread(Server server, Socket clientSocket) throws IOException {
this.server = server;
this.socket = clientSocket;
this.inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.outToClient = new BufferedWriter(new InputStreamReader(socket.getOutputStream()));
}
public void run() {
while (true) {
try {
String line = inFromClient.readLine();
if(line != null) {
String[] clientCommand = line.split(" ");
String commandType = clientCommand[0];
if (!commandType.equalsIgnoreCase("QUIT")) {
switch (commandType) {
case "JOIN":
playerName = clientCommand[1];
System.out.println(playerName + " joined");
Server.players.add(this);
break;
case "PLAY":
//nothing yet
break;
case "MSG":
//nothing yet
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
还有客户:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class Client {
private static int gameID;
private static int order;
private static String opponent;
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("Usage: java Client <serverIp>");
System.exit(1);
}
String serverIP = args[0];
int serverPort = 8945;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket(serverIP, serverPort);
BufferedWriter outToServer = new OutputStreamWriter(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = inFromUser.readLine();
String[] commandSentence = line.split(" ");
String userCommandType = commandSentence[0];
while (!userCommandType.equals("/exit")){
switch (userCommandType){
case "/enter":
String nickname = commandSentence[1];
outToServer.write("JOIN "+ nickname + '\n');
outToServer.flush();
while (true){
String serverLine = inFromServer.readLine();
String[] serverCommand = serverLine.split(" ");
String serverCommandType = serverCommand[0];
if(serverCommandType.equalsIgnoreCase("START")){
gameID = Integer.parseInt(serverCommand[1]);
order = Integer.parseInt(serverCommand[2]);
opponent = serverCommand[3];
System.out.printf("%5s %5s %5s",gameID,order,opponent);
break;
}
}
case "/play":
//nothing yet
break;
case "/msg":
//nothing yet
break;
}
}
}
}
它看起来像是在某个地方进入了死锁,并且由于某种原因,除非在调试中运行,否则永远不要在 Serverclass 上输入它向客户端发送数据
(顺便说一句,我使用 get(0) 和 get(1) 仅用于测试目的)
编辑:好吧,我的愚蠢错误是当客户端向服务器发送数据时我忘记添加outToServer.flush();。但是我的主要问题仍然存在,当我通过对每个客户端键入“/enter if 语句。
【问题讨论】:
-
您的程序描述含糊不清。 “死锁”是什么意思?实际发生了什么,或没有发生什么?哪个
if永远不会被输入,!st.isAlive()一个? -
对不起。这取决于现在,当我开始这个问题时,我会说是的。但正如@EJP 所说,我已将
DataOutputStream更改为BufferedReader,现在它挂得更早了。我现在无法进行太多测试,但它看起来像是在 ServerThread 尝试readLine()时发生的。 -
您为什么希望输入
if?为什么线程不存在? -
抱歉,我之前没有
while(true),这就是原因。 -
您只需要在打开套接字时测试玩家的数量。但是您的测试是在套接字建立之后立即进行的,并且可能在客户端发送 JOIN 之前。
标签: java multithreading sockets