我想知道我如何能够从服务器向客户端发送消息。我是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());
}
}
}
答案 0 :(得分:0)
我已经找到了问题,并在两个课程中为你修复了这些问题,但在我给你代码之前,让我们来谈谈你为什么没有完全正常工作。
在client
代码中,您正确设置了流,并连接到服务器,但在您尝试向服务器发送消息后,就有了这段代码:
//close the stream once we are done with it
dataOut.close();
如果您以后要等待回复,请不要关闭outputstream
,如果这是直接的单向消息,(客户 - >服务器),仅此而已,这将是好的。因为您有这个,简单来说,它会关闭server
和client
之间的套接字通信。
之后,我注意到你有另一个名为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());
}
}*/