服务器无法读取数据

时间:2015-02-13 01:45:08

标签: java sockets server

我修改了Java Socket Tutorials代码以允许客户端发送字符串数组,服务器将数组传回,并更改了数组中的字符串。它工作正常。

现在我正在尝试创建一个充当服务器组件的服务器类。该组件基本上只接收来自客户端的数据并打印客户端数据。但是,服务器接受连接但不读取。因此,为了看看发生了什么,我试图从main运行一个服务器套接字。即使这样也行不通。我不确定为什么教程代码可以工作,但是当我在我的代码中执行完全相同的操作时。我不明白这种奇特行为的原因。

以下是服务器的Java教程代码

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

public class Server {
public static void main(String[] args) throws IOException {

   int portNumber = Integer.parseInt(args[0]);

    try 
    (
                ServerSocket serverSocket =
                    new ServerSocket(Integer.parseInt(args[0]));
                Socket clientSocket = serverSocket.accept();     

                ObjectInputStream objIn = new     ObjectInputStream(clientSocket.getInputStream());
                ObjectOutputStream objOut = new ObjectOutputStream(clientSocket.getOutputStream()); 
    ) {
                String str[][] = (String [][])objIn.readObject();

                if(str != null)
                {   for(int i = 0; i<str.length;i++)
                        for(int j = 0; j<str[i].length;j++)
                            System.out.println(str[i][j]);

                    for(int i = 0; i<str.length;i++)
                        for(int j = 0; j<str[i].length;j++)
                            str[i][j] ="Success";
                    objOut.writeObject(str);
                }

    } catch (IOException | ClassNotFoundException ecp) {
        System.out.println("Exception caught when trying to listen on port "
            + portNumber + " or listening for a connection");
        System.out.println(ecp.getMessage());
    }
}
}

以下是Java Tutorial的客户端

public class EchoClient {
public static void main(String[] args) throws IOException {

    if (args.length != 2) {
        System.err.println(
            "Usage: java EchoClient <host name> <port number>");
        System.exit(1);
    }

    String hostName = args[0];
    int portNumber = Integer.parseInt(args[1]);

    try (
        Socket echoSocket = new Socket(hostName,portNumber);    
        ObjectOutputStream objOut = new ObjectOutputStream(echoSocket.getOutputStream());
        ObjectInputStream objIn = new ObjectInputStream(echoSocket.getInputStream());   
        PrintWriter out =
            new PrintWriter(echoSocket.getOutputStream(), true);
        BufferedReader in =
            new BufferedReader(
                new InputStreamReader(echoSocket.getInputStream()));
        BufferedReader stdIn =
            new BufferedReader(
                new InputStreamReader(System.in))

    ) {
       String str[][] = new String[8][8];
       for(int i = 0; i<str.length;i++)
        for(int j = 0; j<str[i].length;j++)
            str[i][j] = "Test";
       objOut.writeObject(str);
        System.out.println("String array sent");

       str = (String[][])objIn.readObject();
       for(int i = 0; i<str.length;i++)
        for(int j = 0; j<str[i].length;j++)
            System.out.println(str[i][j]);


    } catch (UnknownHostException  e) {
        System.err.println("Don't know about host " + hostName);
        System.exit(1);
    } catch (IOException e) {
        System.err.println("Couldn't get I/O for the connection to " +
            hostName);
        System.exit(1);
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
}
}

现在,以下是我在EchoClient发送数据时无法读取的简单服务器尝试。它连接但不读。

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

public class Server 
{

public static void main (String[] args)
{

    try {
        ServerSocket serv = new ServerSocket(8000);
        Socket client = serv.accept();

        ObjectInputStream objin = new  ObjectInputStream(client.getInputStream());
        String[][] str = (String[][]) objin.readObject();

        for(int i = 0; i<str.length;i++)
            for(int j = 0; j<str[i].length;j++)
                str[i][j] ="Success";

        System.out.println(str[0][0]);
    } catch (IOException | ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

请让我知道我哪里出错了。请注意,Java教程类EchoServer和EchoClient按预期工作。但是我无法自己复制它。 Server类接受EchoClient但不读取。

编辑:以下是我的固定尝试。这按预期工作。

服务器类:

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

public class Server 
{
ServerSocket serverSocket;
Socket clientSocket;
String hostname;
int portNo = 8000;
String clientData;
int count = 0;
public Server()
{
    try {
        serverSocket = new ServerSocket(portNo);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
public void startReceiving()
{
    try {
        if(clientSocket == null)
        {   clientSocket = serverSocket.accept();
            System.out.println("Client Connected");
        }

                ObjectInputStream objIn = new ObjectInputStream(clientSocket.getInputStream());

                //String strtemp[][];
                    String data;
                while(true)
                {
                    if((data = (String)objIn.readObject()) != null)
                    {
                        this.clientData = data;
                        System.out.println(this.clientData);

                        break;
                    }

                    /*if((strtemp = (String[][]) objIn.readObject())!= null)
                    {
                        str = strtemp;
                        System.out.println("received data");
                        for(int i = 0; i<str.length;i++)
                            for(int j = 0; j<str[i].length;j++)
                                System.out.println(str[i][j]);
                    }
                    else
                        System.out.println("no data received");*/
                }
                sendData();

            } catch (IOException | ClassNotFoundException e) {
                // TODO Auto-generated catch block
                //e.printStackTrace();
                try {
                    clientSocket.close();
                    clientSocket = null;
                    startReceiving();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

            }


}
public void sendData()
{
    /*for(int i = 0; i<str.length;i++)
        for(int j = 0; j<str[i].length;j++)
            str[i][j] ="Success";*/
            this.clientData = "client request response" + count;
            count++;
            ObjectOutputStream objOut;
            try {
                objOut = new ObjectOutputStream(clientSocket.getOutputStream());
                objOut.writeObject(this.clientData);
                objOut.flush();
                startReceiving();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

}
public static void main (String[] args)
{
    Server server = new Server();
    server.startReceiving();

}
}

以下是客户:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class TestClient
{
Socket connection;
String hostname = "localhost";
int portNo = 8000;
String incomingData;
int count;
public TestClient()
{
    try {
        connection = new Socket(hostname,portNo);
        count = 0;
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
public void receiveData()
{
    ObjectInputStream in;
    try {
        in = new ObjectInputStream(this.connection.getInputStream());
        String serverMessage;
        while (true)
        {
            if((serverMessage = (String)in.readObject()) != null)
                {
                System.out.println(serverMessage);
                break;
                }
        }
        if(count < 5)
            sendData();
        else
            {
                in.close();
                this.connection.close();
            }

    } catch (IOException | ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //

}
public void sendData()
{
    try {
        ObjectOutputStream out = new ObjectOutputStream(connection.getOutputStream());
        out.writeObject("Client request" + count);
        out.flush();
        count++;
        receiveData();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
public static void main(String args[])
{
    TestClient testClient = new TestClient();
    testClient.sendData();

}
}

2 个答案:

答案 0 :(得分:0)

您的客户端创建了ObjectInputStream但服务器没有创建相应的ObjectOutputStream,因此客户端阻止等待从未发送的对象流标头。

此外,你应该摆脱所有ReadersWriters.你不能在同一个套接字上组合不同类型的读/写/流。

此外,您的服务器无法正常关闭套接字。

此外,错误消息“无法获得I / O ...”毫无意义。我知道它来自Java Tutorial,几十年前我向他们抱怨过它,但是你永远不应该编写自己的错误信息并抛弃像这样的异常附带的错误信息。

答案 1 :(得分:0)

您无法正确理解此应用程序的设计方式。

您删除了发送str [i] [j]的部分,但仍然在循环中将其设置为成功,这是不合逻辑的。首次运行时,服务器将不会读取任何内容,因此它永远不会为数组设置任何值,这就是为什么System.out.println(str[0][0])不打印任何内容。

您必须明白,在本教程的示例中,第一个循环读取了接收的内容

for(int i = 0; i<str.length;i++)
    for(int j = 0; j<str[i].length;j++)
        System.out.println(str[i][j]);

然后第二个循环只是在任何地方写入成功并将数据重新发送到EchoClient

for(int i = 0; i<str.length;i++)
    for(int j = 0; j<str[i].length;j++)
        str[i][j] ="Success";
objOut.writeObject(str);

使用此main

public static void main (String[] args)
{
    int portNumber = 8000;
    try {
        ServerSocket serv = new ServerSocket(portNumber);
        Socket client = serv.accept();

        ObjectInputStream objin = new  ObjectInputStream(client.getInputStream());
        ObjectOutputStream objOut = new ObjectOutputStream(client.getOutputStream()); 
        String str[][] = (String[][]) objin.readObject();

        if(str != null)
        {
            for(int i = 0; i<str.length;i++)
                for(int j = 0; j<str[i].length;j++)
                    System.out.println(str[i][j]);

            for(int i = 0; i<str.length;i++)
                for(int j = 0; j<str[i].length;j++)
                    str[i][j] ="Success";
            objOut.writeObject(str);
        }

        System.out.println(str[0][0]);
    } catch (IOException | ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

您使用的是哪一个,但我重新添加第二个循环和写入的位置将在客户端和服务器上打印。

您还应该考虑在finally块中处理Socket终止,以确保它在您的程序发生任何事情时都已关闭。

try
{
...
}
catch(IOEXception e)
{
...
}
finally
{
    if(socket != null)
        socket.close();
}

确保在try范围之外声明套接字,以便在finally中可以访问它。