如何从服务器获取客户端消息的响应

时间:2017-11-10 01:58:37

标签: java sockets networking server client

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

一旦客户端将“first”消息发送到服务器,我想将“message 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());
    }
   }
}

1 个答案:

答案 0 :(得分:0)

我已经找到了问题,并在两个课程中为你修复了这些问题,但在我给你代码之前,让我们来谈谈你为什么没有完全正常工作。

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

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

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

之后,我注意到你有另一个名为ClientListener的课程,但愚蠢的是,它从未被调用过!因此,当它尝试发送回复时,它会在服务器端导致错误,显然,客户端没有收听任何内容。所以我修复了它并将此代码添加到try类的ClientWriter语句中。

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());
}
   }*/