【问题标题】:How can i get a response from the server to a client message如何从服务器获得对客户端消息的响应
【发布时间】:2018-04-23 04:43:23
【问题描述】:

我想知道如何将消息从服​​务器发送回客户端。我是 Java 新手,并且已经搜索了问题,但是使用的代码对我一直在学习的内容不熟悉。我已经尝试过这样做,但是我不能完全让它将消息发送回客户端。

一旦客户端将消息“首先”发送到服务器,我想从服务器发送消息“revieved”消息。

任何关于解释的帮助将不胜感激!

客户代码:

import java.io.*;
import java.net.*;

public class Client {

//Main Method:- called when running the class file.
public static void main(String[] args){ 

    //Portnumber:- number of the port we wish to connect on.
    int portNumber = 15882;
    //ServerIP:- IP address of the server.
    String serverIP = "localhost";

    try{
        //Create a new socket for communication
        Socket soc = new Socket(serverIP,portNumber);

        // create new instance of the client writer thread, intialise it and 
start it running
        ClientWriter clientWrite = new ClientWriter(soc);
        Thread clientWriteThread = new Thread(clientWrite);
        clientWriteThread.start();

    }
    catch (Exception except){
        //Exception thrown (except) when something went wrong, pushing 
message to the console
        System.out.println("Error --> " + except.getMessage());
    }
  }
}

//This thread is responcible for writing messages
 class ClientWriter implements Runnable
 {
 Socket cwSocket = null;

 public ClientWriter (Socket outputSoc){
    cwSocket = outputSoc;
 }   
 public void run(){
    try{
        //Create the outputstream to send data through
        DataOutputStream dataOut = new 
DataOutputStream(cwSocket.getOutputStream());

        System.out.println("Client writer running");

        //Write message to output stream and send through socket
        dataOut.writeUTF("First");     // writes to output stream
        dataOut.flush();                       // sends through socket 

        //close the stream once we are done with it
        dataOut.close();
    }
    catch (Exception except){
        //Exception thrown (except) when something went wrong, pushing 
message to the console
        System.out.println("Error in Writer--> " + except.getMessage());
    }
 }
}

class ClientListener implements Runnable
{
Socket clSocket = null;

public ClientListener (Socket inputSoc) {
    clSocket = inputSoc;
}

public void run() {
    try {

        // need to write here to recieve message 
        DataInputStream dataIn = new 
DataInputStream(clSocket.getInputStream());           // new stuff
        String msg = dataIn.readUTF();
        System.out.print(msg);

    }
    catch (Exception except){
        //Exception thrown (except) when something went wrong, pushing 
message to the console
        System.out.println("Error in Writer--> " + except.getMessage());
    }
  }


}

服务器代码:

import java.io.*;
import java.net.*;

public class Serv {

//Main Method:- called when running the class file.
public static void main(String[] args){ 

    //Portnumber:- number of the port we wish to connect on.
    int portNumber = 15882;
    try{
        //Setup the socket for communication 
        @SuppressWarnings("resource")
        ServerSocket serverSoc = new ServerSocket(portNumber);

        while (true){

            //accept incoming communication
            System.out.println("Waiting for client");
            Socket soc = serverSoc.accept();

            DataOutputStream dos = new 
DataOutputStream(soc.getOutputStream());
            dos.writeUTF("Message Recieved");                                                
// new stuff
            dos.flush();                         //need to flush

            //create a new thread for the connection and start it.
            ServerConnetionHandler sch = new ServerConnetionHandler(soc);
            Thread schThread = new Thread(sch);
            schThread.start();
        }
    }
    catch (Exception except){
        //Exception thrown (except) when something went wrong, pushing 
message to the console
        System.out.println("Error --> " + except.getMessage());
    }
  }   
}

class ServerConnetionHandler implements Runnable
{
Socket clientSocket = null;

public ServerConnetionHandler (Socket inSoc){
    clientSocket = inSoc;
}

public void run(){
    try{
        //Catch the incoming data in a data stream, read a line and output 
it to the console
        DataInputStream dataIn = new 
DataInputStream(clientSocket.getInputStream());

        System.out.println("Client Connected");
        //Print out message
        System.out.println("--> " + dataIn.readUTF());

        //close the stream once we are done with it
        dataIn.close();
    }
    catch (Exception except){
        //Exception thrown (except) when something went wrong, pushing 
message to the console
        System.out.println("Error in ServerHandler--> " + 
except.getMessage());
    }
   }
}

【问题讨论】:

    标签: java sockets networking server client


    【解决方案1】:

    我已经为你找到了两个类中的问题并修复了它们,但在我给你代码之前,让我们先谈谈为什么你的不完全有效。

    client 代码中,您正确设置了流,并连接到服务器,但是在您尝试向服务器发送消息之后,出现了这段代码:

    //close the stream once we are done with it
    dataOut.close();
    

    如果您稍后要等待回复,请不要关闭您的outputstream,如果这是一条直接的单向消息(客户端->服务器),仅此而已,这没关系。因为你有这个,简单来说,它关闭了serverclient 之间的套接字通信。

    在那之后,我注意到你有另一个类叫做ClientListener,但愚蠢的是,它从来没有被调用过!因此,当它试图发送回复时,它会在服务器端导致错误,很明显,客户端没有在监听任何东西。所以我修复了它,并在ClientWriter 类的try 语句中添加了这段代码。

    ClientListener listener = new ClientListener(cwSocket);
    new Thread(listener).start();
    

    现在我们可以转到serv 类,看看那里发生了什么。 我立即注意到的一个大问题是,一旦服务器初始化并等待client 连接,它就向客户端发送了响应,而没有读取它必须说的任何内容!在发回任何数据之前,最好先阅读客户端发送给您的内容,否则可能会导致错误。 但是很遗憾,您有一个 ServerConnectionHandler 类来监听传入的数据,但是在您向 client 发送回复后调用了该类。它应该在发送回复之前就已经监听,不仅是为了防止错误,而且还可以监听数据,因为在输出流写入内容之后你无法监听数据(除非服务器构建在一种不同的方式。) 我将serv 课程缩短了很多,但总的来说,对于初学者来说非常棒!以下是修改后的工作类:

    客户

    import java.io.*;
    import java.net.*;
    
    public class Client {
    
    
    public static void main(String[] args){ 
    
    //Portnumber:- number of the port we wish to connect on.
    int portNumber = 15882;
    
    //ServerIP:- IP address of the server.
    String serverIP = "localhost";
    
    try{
        //Create a new socket for communication
        Socket soc = new Socket(serverIP, portNumber);
    
        // create new instance of the client writer thread, intialise it and start it running
        ClientWriter clientWrite = new ClientWriter(soc);
        new Thread(clientWrite).start();
        //Shortened code a bit.
    
        //Thread clientWriteThread = new Thread(clientWrite);
        //clientWriteThread.start();
    
    
    
    
    
    }
    catch (Exception except){
        //Exception thrown (except) when something went wrong, pushing message to the console
        System.out.println("Error --> " + except.getMessage());
    }
    }}
    
    
    
    
    
    
    //This thread is responcible for writing messages
    class ClientWriter implements Runnable
     {
    
     Socket cwSocket = null;
    
     public ClientWriter (Socket outputSoc){
    cwSocket = outputSoc;
     }   
    
    
    public void run(){
    try{
        //Create the outputstream to send data through
        DataOutputStream dataOut = new DataOutputStream(cwSocket.getOutputStream());
    
        System.out.println("Client writer running");
    
        //Write message to output stream and send through socket
        dataOut.writeUTF("First");     // writes to output stream
        dataOut.flush();               // sends through socket 
    
        //close the stream once we are done with it
        //dataOut.close();
            //Closing the stream will close the connection between the server and client.
            //DO NOT close an input stream or output stream when communicating with
            //each other, unless it is one way communication...
    
    
       //Where is the listener? It's never called, so we can't listen for anything!
       ClientListener listener = new ClientListener(cwSocket);
       new Thread(listener).start();
    
    }
    catch (Exception except){
        //Exception thrown (except) when something went wrong, pushing message to the console
        System.out.println("Error in Writer--> " + except.getMessage());
        except.printStackTrace();
    }
     }
    }
    
    
    
    
    class ClientListener implements Runnable
    {
    Socket clSocket = null;
    
    public ClientListener (Socket inputSoc) {
    clSocket = inputSoc;
    }
    
    public void run() {
    try {
    
        // need to write here to recieve message 
        DataInputStream dataIn = new DataInputStream(clSocket.getInputStream());           // new stuff
        String msg = dataIn.readUTF();
        System.out.print(msg);
    
    
    
    }
    catch (Exception except){
        //Exception thrown (except) when something went wrong, pushing message to the console
        System.out.println("Error in Writer--> " + except.getMessage());
        except.printStackTrace();
    }
      }
    
    
    }
    

    服务器

    import java.io.*;
    import java.net.*;
    
    public class Serv {
    
    //Main Method:- called when running the class file.
    public static void main(String[] args){ 
    
    //Portnumber:- number of the port we wish to connect on.
    int portNumber = 15882;
    try{
        //Setup the socket for communication 
        ServerSocket serverSoc = new ServerSocket(portNumber);
    
        while (true){
            //accept incoming communication
            System.out.println("Waiting for client");
            Socket soc = serverSoc.accept();
    
            /* It's best to initialize both the input and output streams at the same time
             * Make sure you read what the other stream said before writing to it,
             * or it can be a cluttered error causing mess.
            */
    
            DataOutputStream dos = new DataOutputStream(soc.getOutputStream());
            DataInputStream dataIn = new DataInputStream(soc.getInputStream());
    
    
    
            //Read what client sent us
            System.out.println("Message Received: -->" + dataIn.readUTF());
    
            //Send reply back to client
            dos.writeUTF("Message Recieved");    // new stuff
            dos.flush();                         //need to flush
    
    
            //Close the inputstream and output stream so we can disconnect this user
            //and wait for another one to connect.
            dataIn.close();
            dos.close();
    
    
            //Can not read after writing back, doesn't make sense
    
            //create a new thread for the connection and start it.
            //ServerConnetionHandler sch = new ServerConnetionHandler(soc);
            //Thread schThread = new Thread(sch);
            //schThread.start();
        }
    }
    catch (Exception except){
        //Exception thrown (except) when something went wrong, pushing message to the console
        System.out.println("Error --> " + except.getMessage());
        except.printStackTrace();
    }
    }}
    
    
    
    /*The last code you had was all wrong. Up in the server, you were
     * writing a reply back to the client and then waiting for a response...
     * You can't listen for something after you wrote back (failed to write back
     * anyway due to some problems)
     * You can remove this code below, as it is redundant.
     */
    /*
    class ServerConnetionHandler implements Runnable
    {
    Socket clientSocket = null;
    
    public ServerConnetionHandler (Socket inSoc){
    clientSocket = inSoc;
    }
    
    public void run(){
    try{
        //Catch the incoming data in a data stream, read a line and output it to the console
        DataInputStream dataIn = new DataInputStream(clientSocket.getInputStream());
    
        System.out.println("Client Connected");
        //Print out message
        System.out.println("--> " + dataIn.readUTF());
    
        //close the stream once we are done with it
        dataIn.close();
    }
    catch (Exception except){
        //Exception thrown (except) when something went wrong, pushing message to the console
        System.out.println("Error in ServerHandler--> " + 
                except.getMessage());
    }
       }*/
    

    【讨论】:

    • 哇,非常感谢!我不能要求更好的答案和解释。真的很感激!
    猜你喜欢
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多