客户端和服务器之间的Java套接字交换消息

时间:2012-02-25 15:46:37

标签: java sockets

在阅读有关TCP和UDP套接字的示例后,我自己学习了Oracle Java页面上的socket,但是在Java socket多线程中遇到了麻烦。

我尝试使用这些知识写一些东西来在客户端和服务器之间交换消息。

但是,我想知道客户端何时向多服务器发送消息,服务器有一些条件。

示例:当客户端向服务器发送字母A

服务器将收到并具有类似

的条件
if(inputfromClient.equals("A")){
     // how to make input fromClient is null after get message (inputstream) from client?
}

在上面的代码片段的注释中,您可以看到我的问题,因为在客户端发送输入为A之后,客户端将发送下一个字母,如B,在这样的结构中:

if(inputfromClient.equals("A")){
    if(inputfromClient.equals("B")){
       //some condition
    }
}

我的服务器代码如下:

 public class TCPServerThread extends Thread{

    Socket client = null;
    BufferedReader in;
    String statusBuffer = new String();
    String intputLine, outputLine;
    public TCPServerThread(Socket socket){
        client = socket;
    }

    public void run(){
        try {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(TCPServerThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            PrintWriter out = new PrintWriter(client.getOutputStream(),true);
            in = new BufferedReader(new InputStreamReader(client.getInputStream()));
            gameHandle g = new gameHandle();
            boolean condition = true;

                while((intputLine=in.readLine()) != null){
                    outputLine = g.processInput(intputLine);
                    out.println(outputLine);
                    System.out.println(outputLine);

                }



                  out.close();
                  in.close();
                  client.close();


        } catch (IOException ex) {
            Logger.getLogger(TCPServerThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


}

和我的客户代码:

  public class ClientTCP {

    public static void main(String[] args) {
        try {
            Socket socket;
            PrintWriter out = null;
            BufferedReader in = null;
            try {
                socket = new Socket("localhost", 4444);
                out = new PrintWriter(socket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            } catch (UnknownHostException ex) {
                Logger.getLogger(ClientTCP.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(ClientTCP.class.getName()).log(Level.SEVERE, null, ex);
            }

            BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
            String fromServer;
            String fromUser;
            fromUser = stdIn.readLine();
            while(fromUser!= null){

                out.println(fromUser);
                //System.out.println(in.readLine());
            }
        } catch (IOException ex) {
            Logger.getLogger(ClientTCP.class.getName()).log(Level.SEVERE, null, ex);
        }
   }


}

非常感谢。

被修改

好像我之前提到的那样有意义

客户端向服务器发送消息

  

客户:onePMode

     

客户:互联网

...

和服务器从客户端获取消息并进行比较

if(inputLine.equals("onePMode")){
 // it will continue to compare inputline is satisfy with sub condition
  if(inputLine.equals("internet"){
   //do something
   }

}

被修改

GameHandle处理输入

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package srpserver;

import java.net.Socket;
import java.util.Random;

/**
 *
 * @author ***
 */
public class gameHandle {

    private String modePlay = "";
    private String wait = "wait";
    private String status = wait;
    private String keyword = "";
    private Socket client;
    private String letter = "";
    private String onePMode ="onePMode";
    private String getWord = "getWord";
    private String twoPMode = "twoPMode";
    private String waitForPlayer = "waitforPlayer";
    private String ready = "ready";
    private String question = "question";

    public gameHandle(){}

    public gameHandle(Socket socket,String Mode, String keyword, String letter){
        client = socket;
        this.keyword = keyword;
        this.letter = letter;
        modePlay = Mode;
    }
    //array with word will be rando,
    String[] words = {"laptop", "network", "device", "game", "mobile",
    "word", "november", "december", "signal", "internet","localhost","boot", "socket",
    "client", "server", " port", "exception", "java", "dotnet","singleton", "ejb","hibernate",
    "computer", "microsoft", "lan"};

    //this method get random word from array    
    public String getWord(){
        Random r = new Random();
        String randomString = words[r.nextInt(words.length)];
        return randomString;
    }



    public String processInput(String inputString){
        String outPut = "";
            if(status.equals("wait")){
                if(inputString.equals(onePMode)){
                    status = question;
                    outPut = "hello";
                   // outPut = question;
                }
            }else if(status.equals(question)){
                if(inputString.equals(getWord)){
                    /*keyword = getWord();
                    outPut = getWord();
                    System.out.println(keyword);
                    status = question;*/
                    outPut = "getworrdddrdd";
                    System.out.println("get worddddddddd");

                }else if(keyword.contains(inputString)){
                    System.out.println("containt");
                }
            }
        return outPut;
    }





    public static void main(String[] args) {
        gameHandle a = new gameHandle();
        System.out.println(a.getWord());

    }
}

2 个答案:

答案 0 :(得分:0)

这可能是解决您问题的最简单方法。

public class TCPServerThread extends Thread{

    Socket client = null;
    BufferedReader in;

    String statusBuffer = new String();

    public TCPServerThread(Socket socket){
        client = socket;
    }

    public void run() {
    try {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

        PrintWriter out = new PrintWriter(client.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(
                client.getInputStream()));
        String intputLine, outputLine;

        intputLine = in.readLine();

        while (intputLine != null) {
            if(intputLine.equals("close")){
                break;
            }
            processResponse(intputLine);
            intputLine = in.readLine();             
        }

        out.close();
        in.close();
        client.close();

    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public void processResponse(String response) {

    // reset the statusBuffer so that we can process new commands from
    // client
    if (response.equals("reset")) {
        statusBuffer = new String();
        System.out.println("reset");
    } else {
        statusBuffer = statusBuffer + "#" + response;
    }

    if (statusBuffer.equals("#onePMode")) {
        System.out.println("#onePMode");
    } else if (statusBuffer.equals("#onePMode#internet")) {
        System.out.println("#onePMode#internet");
    } else if (statusBuffer.equals("#onePMode#play")) {
        System.out.println("#onePMode#play");
    }

}

}

我还在您的客户端代码中发现了一个错误。更正后的代码如下

public class ClientTCP {

    public static void main(String[] args) {
        try {
            Socket socket = null;
            PrintWriter out = null;
            BufferedReader in = null;
            try {
                socket = new Socket("localhost", 1000);
                out = new PrintWriter(socket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));

            String fromServer;

            String fromUser  = stdIn.readLine();
            while(fromUser!= null){
                out.println(fromUser);

                if(fromUser.equals("close")){
                    break;
                }

                fromUser = stdIn.readLine();

            }
            out.close();
            in.close();
            socket.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
   }

} 

我在我的头上执行了程序并且运行成功。现在你不应该有任何问题。

答案 1 :(得分:0)

我认为你想要的是根据以前的状态做出决定。然后你需要的只是一个面向对象的状态机。 如果客户端从初始状态输入'A',则服务器应该期望'B''C'作为下一个输入。如果客户端在服务器处于状态'B'时输入'A',则服务器应该期望'D'或'E'作为下一个输入。如果这是你想要的,你应该使用State Design Pattern

  • 您拥有的每个州都应该由一个对象代表。

  • 首先,您需要为状态创建Interface并派生您的 来自它的状态。

  • 然后你应该创建一个封装类来封装你的状态。 这个包装类充当状态机。它应该维持一个 引用“当前”状态对象。

当客户输入一个字符时,它将被传递给包装器实例。然后包装器将它传递给当前状态对象。然后,当前State对象将处理该数据并决定机器的下一个状态。它将创建下一个State(Object)并更新包装类的“当前”状态引用。然后,下一个客户端输入将由新创建的State对象处理。

这是一个例子

  

状态界面

public interface State {

    void perform(GameHandler context, String data);
}
  

包装类

public class GameHandler {

    State current_state; // holds the current state of the state machine

    // Initial state should be passed to the constructor 
    public GameHandler(State current_state) { 
        this.current_state = current_state;
    }

    // Sets the next state of the state machine
    // Called by State objects
    public void setNextState(State mystate) {
        this.current_state = mystate;
    }

    // Outside world will communicate with state machine using this method 
    public void processRequest(String data){
        current_state.perform(this,data);
    } 
}
  

州实施

public class State_A implements State {

    @Override
    public void perform(GameHandler context, String data) {
        /* Process input data.
         * Based on your processing, decide the next state
         * Then set that sate (assuming it as State_B)
         */
        context.setNextState(new State_B());
    }
}

public class State_B implements State {

    @Override
    public void perform(GameHandler context, String data) {
        /* process input data.
         * based on your processing, decide the next state
         * then set that sate (assuming it as State_C)
         */
        context.setNextState(new State_C());

    }
}

如何在您的服务器中使用

...

// Assuming State_A as the initial state
GameHandler g = new GameHandler(new State_A());
boolean condition = true;

      while((intputLine=in.readLine()) != null)
      {
         g.processRequest(intputLine);
      }

...