我在Java开发了一个客户端-服务器游戏(称为“Set”)。
在调试过程中遇到了一个非常尴尬的问题:
如果在同一台机器上同时运行客户端和服务器(客户端连接到localhost),这个游戏工作得很棒(如果我运行服务器和大量客户端的话也是如此)。
但是,如果我在两台不同的机器上运行客户端和服务器,那么客户端和服务器都挂起了Inputstream readLine方法。
我会提到我正在使用writeBytes方法来写入数据,但是我总是用\n(如前所述,系统在一台机器上工作得很好!)
系统的体系结构如下:
public SetServer(){
this.deck = initCardsList();
Collections.shuffle(this.deck);
shownCards = new Card[12];
for(int i = 0; i<12; i++){
Card c = this.deck.removeFirst();
shownCards[i]=c;
}
while(!isSetOnTable()){
Card c = this.deck.removeFirst();
this.deck.addLast(shownCards[0]);
shownCards[0]=c;
}
playersQueue = new LinkedList<String>();
clients = new LinkedList<ServerOperation>();
try{
ServerSocket welcomeSocket = new ServerSocket(6789);
while(true)
{
if(currNumOfPlayers<5){
System.out.println("Waiting for connection...");
Socket connectionSocket = welcomeSocket.accept();
String line = (new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()))).readLine();
currNumOfPlayers++;
playersQueue.addLast(line);
ServerOperation client = new ServerOperation(connectionSocket,this, line);
clients.add(client);
Thread t = new Thread(client);
t.start(); //<--- This thread listens to client's request
notifyPlayersAdded(line,new DataOutputStream(connectionSocket.getOutputStream())); //<-----This method sends 3 lines of data
}
}
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
ServerOperation的运行方法:
public void run(){
if(socket==null){
return;
}
else{
try{
// this.out.writeBytes("NewConnection:" + this.parent.STATUS+"\n");
// this.parent.notifyCards();
while(true){
String line = this.br.readLine();
String command = line.split(":")[0];
if(command.equals("SetRequest")){
String[] cards = line.substring(line.indexOf(':')+1).split(" ");
Card c1,c2,c3;
c1 = new Card(
CardShape.values()[(int)(cards[0].charAt(3)-'0')],
CardNumber.values()[(int)(cards[0].charAt(2)-'0')],
CardFill.values()[(int)(cards[0].charAt(1)-'0')],
CardColor.values()[(int)(cards[0].charAt(0)-'0')]);
c2 = new Card(
CardShape.values()[(int)(cards[1].charAt(3)-'0')],
CardNumber.values()[(int)(cards[1].charAt(2)-'0')],
CardFill.values()[(int)(cards[1].charAt(1)-'0')],
CardColor.values()[(int)(cards[1].charAt(0)-'0')]);
c3 = new Card(
CardShape.values()[(int)(cards[2].charAt(3)-'0')],
CardNumber.values()[(int)(cards[2].charAt(2)-'0')],
CardFill.values()[(int)(cards[2].charAt(1)-'0')],
CardColor.values()[(int)(cards[2].charAt(0)-'0')]);
this.parent.checkIfSetAndNotify(c1,c2,c3,this.playerId);
}
}
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
客户端代码:
public SetClient()
{
String sentence;
this.myCards = new LinkedList<Card>();
try{
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
clientSocket = new Socket("10.0.0.3", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.flush();
String name = sayHelloAndGetUserName();
outToServer.writeBytes(name);
outToServer.flush();
sentence = inFromServer.readLine();
sayWelcome(sentence);
ClientOperation clnOper = new ClientOperation(clientSocket,this);
Thread t = new Thread(clnOper);
t.start(); //<---this thread listens to the server for messages (suppose
//to catch the first 3 lines. In practice, catches only the first one.
while(!GameOver)
{
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //<-----listens to the user's input
String line = br.readLine();
String[] choices = line.split(" ");
int c1 = Integer.parseInt(choices[0]);
int c2 = Integer.parseInt(choices[1]);
int c3 = Integer.parseInt(choices[2]);
sendSetMessage(outToServer,c1,c2,c3);
}
catch(Exception ex){
System.out.println("Error listening to system.in...");
}
}
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
ClientOperation的代码:
public void run()
{
if(socket==null){
return;
}
else{
try{
this.br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
String line = this.br.readLine();
String command = line.split(":")[0];
String value = line.split(":")[1];
if (command.equalsIgnoreCase("Deck"))
{
ConvertStringToCards(value);
this.parent.PopulateCards(shownCards);
}
else if (command.equalsIgnoreCase("Points"))
{
System.out.println("Points: " + value);
}
else if(command.equalsIgnoreCase("NewPlayer")){
System.out.println(value + " has joined the game !\n");
}
else if(command.equalsIgnoreCase("Hint")){
this.parent.printHint(ConvertStringToHint(value));
}
}
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
一般情况下,客户机服务器项目在一台机器上运行良好,但却挂在两台单独的机器上的原因是什么?
p.s.当我在不同的机器上一步一步地调试客户端和服务器时,它也能很好地工作。
先谢谢你,
如果不是localhost的问题,那么最有可能的是检查防火墙是否存在禁用并再次检查,其次运行netstat检查服务器是否监听所有接口,而不仅仅是环回。
在linux上,您可以尝试:
netstat -nat | grep 6789
它可能也可以在windows power Shell中工作。如果服务器正在运行/监听您的外部ip并且客户端仍然无法连接并且防火墙被禁用,则安装wireshark并查看网络上发生了什么。
我在做一个客户端/服务器应用程序。目前它的功能很好,但我需要添加一个“选项”。 server类如下所示: 因此许多客户端都能够连接到服务器。我的观点是:我希望一个连接的客户机(比如说,Client1)能够向他选择的另一个连接的客户机(Client2)发送一些东西。 我的问题是:Client1如何找到/拥有/检索Client2的套接字,因为所有的Client1都通过这个clientSocket在不同
我正在尝试在Java创建一个多客户机/服务器应用程序。我有些问题因为我的线好像纠缠在一起了...这就是我要做的。 > 我有一个服务器类,它通过使用以下代码来接受客户端: while(true){Socket Socket=ServerSocket.Accept();} 我的服务器应该记住所连接的客户端,因此我使用该套接字创建一个名为ClientThread的新线程,并将该线程放在服务器上的列表中
我是编码和Java的新手,我已经创建了一个简单的客户端-服务器程序,客户端可以请求一个文件。它的内容将显示在浏览器页面中,还有一些细节,如数据类型和长度。我现在有一个问题,我不确定如何在浏览器中显示正确连接的服务器响应,如“HTTP/1.1 200 OK”和关闭的连接,如“Connection: close”。我有一个处理响应的方法,如下所示: 对我如何做到这一点有什么建议吗?非常感谢。
编辑2:我切换到,并用包装客户端工厂,这样设备就可以很好地到达后端。但是当后端发回一些东西时,我会得到错误的出站套接字,客户机套接字死亡。我认为这是因为后端没有正确路由消息所必需的头。如何捕获此信息?我的配置类如下:
创建Eureka发现客户端和服务器架构。在客户端有userInfo服务CRUD opeartion。它在启动时显示错误。错误是创建在类路径资源[org/springFramework/cloud/autoconfiure/ConfigurationProperty tiesRebinderAutoConfiguration.class]中定义的名为“配置属性Beans”的bean的错误:合并bea