【问题标题】:Java: How to start Client or Server, depending on if Server is already up?Java:如何启动客户端或服务器,取决于服务器是否已经启动?
【发布时间】:2020-05-06 19:34:24
【问题描述】:

我编写了一个游戏,游戏场地以数组表示。我现在实现了 2 个类,分别称为 Client 和 Server,Client 有一个“发送”按钮。服务器有一个文本区域,其中发送的数据(在我的例子中是一个数组对象)显示为字符串 服务器的一种方式,我稍后会实现两种方式的连接。

我的问题:如果游戏开始,我希望第一个连接的玩家充当主机/服务器,因此初始化服务器。如果第二个人之后在他的电脑上启动游戏,他需要作为客户端连接到已经运行的服务器。如何检查服务器是否已经在运行,从而为第二个玩家创建客户端实例?

提前致谢!

我的客户代码:

package connect4;

import javax.swing.*;

import java.net.*;

import java.awt.event.*;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class ClientTest {

    static protected ObjectOutputStream myoutput;


     public static void main(String[] args) {

      ClientTest client = new ClientTest();

          //test
       }



public ClientTest() {
    System.out.println("Client is connected");
    Window window1=new Window();

        window1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class Window extends JFrame{

    public Window(){

        setBounds(600,300,280,350);

        WindowClient winClient=new WindowClient();

        add(winClient);

        setVisible(true);
        }   

}

class WindowClient extends JPanel{

    public WindowClient(){

        JLabel text=new JLabel("CLIENT");

        add(text);





        mybutton=new JButton("Send");

        SendText textfield= new SendText();

        mybutton.addActionListener(textfield);

        add(mybutton);  

    }

private class SendText implements ActionListener{



        public void actionPerformed(ActionEvent e) {
            //System.out.println(campo1.getText());
            try {
                Socket mysocket=new Socket("localhost",9999);
                System.out.println("Data was sent..");
                ObjectOutputStream myoutput = new ObjectOutputStream(mysocket.getOutputStream());   

                myoutput.writeObject(GridTest.gamefield);

                myoutput.close();

            } catch (UnknownHostException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                System.out.println(e1.getMessage());
            }// meine IP und eine freie Port
        }
    }


        //asd

private JTextField field1;

private JButton mybutton;

}}

我的服务器代码:

package connect4;
import javax.swing.*;
import java.net.*;

import java.awt.*;
import java.io.*;

public class ServerTest  {
    private static char [][] spot = new char [6][7];
    static boolean connected;


    public static void main(String[] args) {
        // TODO Auto-generated method stub

    ServerTest server = new ServerTest();

    }   



public ServerTest() {
    WindowServer mywindow=new WindowServer();

    mywindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class WindowServer extends JFrame implements Runnable  {

    public WindowServer(){

        setBounds(1200,300,280,350);                

        JPanel newpanel= new JPanel();

        newpanel.setLayout(new BorderLayout());

        textarea=new JTextArea();

        newpanel.add(textarea,BorderLayout.CENTER);

        add(newpanel);

        setVisible(true);

        Thread mythread = new Thread(this);

        mythread.start();

        }

    private JTextArea textarea;



    @Override
    public void run() {

        try {
            ServerSocket server=new ServerSocket(9999);//port öfnnen listen und Verbindungen akzeptieren

            while(true) {
            Socket mysocket= server.accept();

            ObjectInputStream myinput=new ObjectInputStream(mysocket.getInputStream());

            Object mymessage = myinput.readObject();

            textarea.append("\n" + mymessage);
            System.out.println(mymessage);
            System.out.println("Data recieved...");
            mysocket.close();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}}

【问题讨论】:

  • 尝试启动服务器。如果遇到绑定异常,请启动客户端。不要反过来做,因为那样会有时间窗口问题。
  • 如何启动服务器或客户端,取决于哪一个已经启动。游戏是一个单独的文件,因此需要有某种 if 语句来检查是否连接为客户端或启动服务器(如果没有服务器)

标签: java sockets tcp server client


【解决方案1】:

一些伪代码:

class ServerClient {
    try {
        connect(remoteServerCredentials);
    } catch (java.io.SocketException exception) {
        //  print failed to connect Starting up as server
        //  Start up the Server()
    }
}

【讨论】:

  • 这里的时间窗口问题。如果您连续快速启动两个客户端,两者都可以获得连接异常,然后都将尝试启动服务器,然后您必须处理第二种故障模式。您应该尝试无条件地启动服务器,然后仅在失败时启动客户端。那样没有时间窗口。
  • 如何检查服务器是否正在运行?
猜你喜欢
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多