有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java多客户端/服务器。处理通讯

从两天以来,我一直在忍受着这些代码的折磨。事实上,我正在开发一个应用程序,它有服务器端和客户端。服务器每秒钟接收一次来自客户端的请求,通过联系数据库处理请求,然后将结果发送回客户端。 我这样做的方式是,如果客户端在服务器之前启动,它将继续尝试连接到给定端口和给定主机上的服务器
1.这是服务器端:

try
    {   
        Client client = new Client(jTable1,jLabel3);
        Thread t = new Thread(client);
        t.start();

    }catch(IOException e){}

类客户端。爪哇

public class Client implements Runnable{

private int svrPort = 0;
ServerSocket serverConnect = null;
static  Socket clientSocket = null;
static  ClientConnectThread t[] = new ClientConnectThread[1000];
JTable jtable;
JLabel jlabel;

public Client(JTable table, JLabel label) throws IOException {

    this.svrPort = 9450;
    this.jtable = table;
    this.jlabel = label;

}

public void run(){
    try{
        serverConnect = new ServerSocket(this.svrPort);

    }catch(IOException e){}
    while(true){
        try{
            clientSocket = serverConnect.accept ();
            for(int i=0; i<=1000; i++){ //I can accept up to 1000 clients
        if(t[i]==null)
        {
            (t[i] = new ClientThread(client, t, jtable, jlabel)).start();
                        System.out.println ("Etat12. Apres bloc try");
            break;
        }
    }
        }catch(IOException e){}
    }
}

}

类ClientThread。爪哇

public ClientThread(Socket socket, ClientThread t[], JTable table, JLabel label){

    this._socket = socket;
    this.jTable = table;
    this.jlabel = label;
    this.totalConnected = 0;       
    this.t = t;
}

public void run(){

    int index = 0;
    try{
        this._output = new PrintWriter(this._socket.getOutputStream ());
        this._input = new BufferedReader(new InputStreamReader(this._socket.getInputStream()));

        while((clientMsg = this._input.readLine ()) != null){
            if(clientMsg.equals ("@CONNECT")){ // If it is the first time the user is signig in, fill the table

                jTable.setValueAt (this._socket.getInetAddress (), index, 0);
                jTable.setValueAt (new Date(), index, 1);
                jTable.setValueAt (new Date(), index, 2);
                totalConnected++;
                jlabel.setText ("");
                jlabel.setText (totalConnected+"");

            }else if(Integer.parseInt (clientMsg) == 1){
                int p = Integer.parseInt (clientMsg);
                this._output = new PrintWriter(this._socket.getOutputStream(), true);
                if (this.getData.connect ())
                {
                    if(this.getData.getDataByType (1).size () == 0){
                    }
                    _output.println (this.getData.getDataByPeriod (1));
                }else{System.out.println("You are not connected to the database server");}

            }else if(Integer.parseInt (clientMsg) == 2){
                int p = Integer.parseInt (clientMsg);
                this._output = new PrintWriter(this._socket.getOutputStream(), true);
                if (this.getData.connect ())
                {
                    if(this.getData.getDataByPeriod (2).size () == 0)System.out.println ("There is no data corresponding");
                    this._output.println (this.getData.getDataByPeriod (2));
                }else{System.out.println("You are not connected to the database server");}


            }else if(Integer.parseInt (clientMsg) == 3){
                int p = Integer.parseInt (clientMsg);
                this._output = new PrintWriter(this._socket.getOutputStream(), true);
                if (this.getData.connect ())
                {
                    if(this.getData.getDataByType (3).size () == 0)System.out.println ("There is no data corresponding");
                    this._output.println (this.getData.getDataByType (30));
                }else{System.out.println("You are not connected to the database server");}


            }else if(Integer.parseInt (clientMsg) == 4){
                int p = Integer.parseInt (clientMsg);
                this._output = new PrintWriter(this._socket.getOutputStream(), true);
                if (this.getData.connect ())
                {
                    if(this.getData.getDataByType (4).size () == 0)System.out.println ("There is no data corresponding");
                    this._output.println (this.getData.getDataByType (60));
                }else{System.out.println("You are not connected to the database server");}


            }else{

            }
        }
        this._input.close ();
        this._output.close ();
    }catch(IOException e){}

}

这是使我的服务器运行的两个类。类客户端。java启动并等待接受连接。当客户端连接时,将创建clientThread的实例并将其关联到客户端。 到目前为止,一切似乎都很顺利

客户端

public class ServerConnect implements Runnable{

public static Socket clientSocket = null;
public static PrintWriter out = null;
public static BufferedReader in = null;
public static int port=9450;
public static String host = "127.0.0.1";
public static JLabel myLabel;
public static JButton button;
public static ResourceMap resourceMap;
private static String serverMsg = "";

public ServerConnect(JLabel jLabel, JButton b)
{
    jLabel.setText ("Trying to contact the server");
    myLabel = jLabel;
    button = b;
    port = Integer.parseInt("9450");
    host = "127.0.0.1";

        try{
            clientSocket = new Socket(host, port);
            }catch(IOException e){e.printStackTrace ();}

}

public void run()
{
    while(true){
        while(!this.connect ())
        {myLabel.setText ("You are not connected to the server : "+host);
         button.setEnabled (false);
            try{
                clientSocket = new Socket(host, port);
            }catch(IOException e){}
        }

        myLabel.setText ("You are connected to the server : "+host);
        button.setEnabled (true);
        try{
           out = new PrintWriter(clientSocket.getOutputStream(), true);
           out.println("@CONNECT");

           in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
           while((serverMsg = in.readLine ()) != null){
                System.out.println ("<=> :"+serverMsg);
           }
        }
        catch(IOException e){e.printStackTrace ();}
    }
}
private boolean connect()
{
    try{
        clientSocket = new Socket(host, port);
        return true;
    }catch(IOException e){}
    return false;
}}

我的问题是,当双方开始时,客户端发送@CONNECT的唯一内容是服务器接收到它,然后全部停止在这里。如果客户端再次发送请求,则服务器不会应答
我希望有人一步一步地告诉我如何设置此应用程序
-服务器端。通过WHILE循环接受线程中的连接
-客户端。在另一个线程中,每次尝试联系服务器以建立连接
-在另一个线程中,客户端再次向服务器发送请求
-服务器是另一个从数据库请求信息并发送回客户端的线程

我非常感谢你的帮助


共 (2) 个答案

  1. # 1 楼答案

    这很简单,但底层技术很复杂 我的解释顺序与我的回答相反

    在主代码中,使用GrizzlyServerFactory启动Grizzlyserver。创建(url),它侦听“127.0.0.1”

    当服务器启动时,它会搜索带有注释@Path的类。。。找到“你的服务”

    因此Grizzly将在url“http://127.0.0.1/FUNNY_SERVICE_V001”上“注册”(或类似的内容)ServiceClass“YourService”(参见I_ServiceCommons)

    嗯。。我们又进入了主代码。我们创建一个MyRequest对象,并创建一个具体服务“service”的实例。更好的名称应该是“ServiceClient”,因为它是客户端的代码。“服务”是用url(“http://127.0.0.1”)创建的,并逐步进入AbstractClient中的公共构造函数代码(用于所有客户端),并创建服务url“http://127.0.0.1/FUNNY_SERVICE_V001”。在AbstractClient内部,将创建一个客户端对象(用于连接/编码处理等)。 当我们想要访问服务器时,我们只需要将MyRequest对象放入“服务”的“getResult”方法中。AbstractClient中的客户端将MyRequest对象转换为XML重新表示(注意其中的@XMLRootElement注释、无参数构造函数和set/get方法),向服务器发送HTTP POST,从而重新创建MyRequest对象

    所以在服务器端。。。 因此,当客户机以正确的方式连接到“http://127.0.0.1/FUNNY_SERVICE_V001”时,服务器将创建YourService的一个实例(需要无参数构造函数)并读取xml,创建transferobject MyRequest并将其放入方法public ResultObject request(final RequestObject yourRequest),因为它使用@POST注释进行注释(在客户机中,我们使用HTTP-POST)。您可以处理MyRequest对象,必须返回一个MyResult对象,该对象将转换为xml,由客户端发送、接收并重新创建为MyResult对象。就这样

  2. # 2 楼答案

    哦,用打印机等把所有东西都放在低电平插座上是个坏主意。 我在过去遇到过几个编码和多线程错误。因此,我的解决方案(当然有点慢,但很容易使用)是:Jersey&;灰熊

    最大的优点是:您可以非常轻松地修改和扩展传输对象,而无需修改传输代码(低级套接字写入)

    一个接口

    public interface I_ServiceCommons {
            public static final String  MEDIATYPE           = "text/xml";
            public static final String  MEDIATYPE_ENCODING  = I_ServiceCommons.MEDIATYPE + "; charset=utf-8";
            public static final String SERIVCENAME = "/FUNNY_SERVICE_V001";
        }
    

    服务器端代码

    @Path(I_ServiceCommons.SERIVCENAME)
    public class YourService {
    
        @POST
        @Produces(I_ServiceCommons.MEDIATYPE)
        @Consumes(I_ServiceCommons.MEDIATYPE)
        public ResultObject request(final RequestObject yourRequest) {
            //process here your request in Server
        }
    }
    

    你的客户

    public class abstract YourAbstractClient{
            protected Logger                            log             = Logger.getLogger(this.getClass());
            protected final String                      serviceUrl;
            private final WebResource                   resource;
    
            public YourAbstractClient(final String url) {
                this.serviceUrl = url + getService();
                this.resource = Client.create().resource(this.serviceUrl);
            }
    
            public abstract String getService();
    
            protected <RES, REQ> RES post(final Class<RES> resultClazz, final REQ req) {
                final Builder builder = this.resource.type(I_ServiceCommons.MEDIATYPE).accept(I_ServiceCommons.MEDIATYPE);
                try {
                    final RES result = builder.post(resultClazz, req);
                    return result;
                } catch (final Exception e) {
                    throw new RuntimeException("Error posting data to [" + this.serviceUrl + "]: " + e.getMessage(), e);
                }
            }
    
        }
    

    您的服务客户端

    public class Service extends YourAbstractClient {
    
        public Service(final String url) {
            super(url);
        }
    
        public MyResult getResult(final MyRequest req) {
            return super.post(MyResult.class, req);
        }
    
        @Override
        public String getService() {
            return I_ServiceCommons.SERIVCENAME;
        }
    }
    

    你的转让对象

    @XmlRootElement
    public class MyRequest implements Serializable {
        public void setRequestType(final int p_AequestType) {
            this.requestType = p_AequestType;
        }
    
        public int getRequestType() {
            return this.requestType;
        }
    }
    

    最后

    String url = "http://127.0.0.1";
    GrizzlyServerFactory.create(url) //starts the server
    MyRequest res = new MyRequest();
    MyResult result = new Service(url).getResult(req); // Corrected