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

问题描述:

我现在已经忍受这两天的代码。事实上,我正在开发一个有服务器端和客户端的应用程序。服务器每秒从客户端接收请求,通过联系数据库来处理请求,然后将结果发送回客户端。
我这样做,如果客户端在服务器之前启动,它将仍然尝试连接到给定端口和给定主机上的服务器。

1.这是服务器侧:

I am suffering with this codes since two days now. In fact I am developping an application which has a server side and the clients side. The server receives request from clients every seconds, treat the request by contacting the database and then send back the result to the client. I do such a way that if the client starts before the server, it will remain trying to connect to the server on the given port and the given host.
1. This is the server side:

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

    }catch(IOException e){}



Class Client.java

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.java类

Class ClientThread.java

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){}

}



These are the two classes that make my server running. The class Client.java starts and waits to accept connection. When a client connects an instance of clientThread is created and associated to the client. Till here every thing seems to be working well.

客户端

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循环的连接

- 客户端。在另一个线程尝试每次联系服务器以建立连接

- 在另一个线程中,客户端发送请求到服务器

- 服务器是另一个线程请求信息

My problem is that when the two sides are starting, the only thing the client sends @CONNECT, the server receives it and all stops here. If the client sends a requests again, the server does not answer.
I would like someone to show me step by step how I can setup this applications
- Server side. Accepts connections in thread with the WHILE loop
- Client side. In another thread to try to contact the server everytime to establish a connection
- In another thread again, client sends request to server
- The server is another thread request the information from the database and sends back to client.

非常感谢您的帮助

Ooohh这是一个坏主意,把一切都放在一个低级别的socket与PrintWriter等
我有过去的几个编码和多线程错误。所以我的(当然有点慢,但易于使用)解决方案是:泽西&最大的优点是:您可以轻松地修改和扩展传输对象,而无需修改传输代码(低级套接字写入)

Ooohh its a bad idea to put everything onto a low level socket with a PrintWriter etc. I got several encoding and multithreading errors in the past. So my (of course a little bit slower, but easy to use) solution is: Jersey & Grizzly.

strong>

The big advantage is: You can modify and extend your transfer objects very easily, without modifying your transport code(the low level socket writing)

接口...

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);
            }
        }

    }

您的ServiceClient ...

Your ServiceClient...

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;
    }
}

您的TransferObjects

Your TransferObjects

@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