Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java套接字编程_Java_Sockets_Network Programming_Objectinputstream - Fatal编程技术网

Java套接字编程

Java套接字编程,java,sockets,network-programming,objectinputstream,Java,Sockets,Network Programming,Objectinputstream,我正在使用java套接字构建一个简单的客户机/服务器应用程序,并尝试使用ObjectOutputStream等 我一直在关注这个url的教程,从一半开始讨论通过套接字传输对象 查看我的客户端代码,但这似乎不起作用,我无法找出什么不起作用。底部注释掉的代码是直接从教程中复制出来的——当我使用它而不是创建客户机对象时,这是有效的 有人能看到我做错了什么吗?您没有在任何地方写入对象 再次查看该链接,您必须在其中写入: oos.writeObject( new Date() ); 在代码中,只有 o

我正在使用java套接字构建一个简单的客户机/服务器应用程序,并尝试使用ObjectOutputStream等

我一直在关注这个url的教程,从一半开始讨论通过套接字传输对象

查看我的客户端代码,但这似乎不起作用,我无法找出什么不起作用。底部注释掉的代码是直接从教程中复制出来的——当我使用它而不是创建客户机对象时,这是有效的


有人能看到我做错了什么吗?

您没有在任何地方写入对象

再次查看该链接,您必须在其中写入:

 oos.writeObject( new Date() );
在代码中,只有

ois.readObject();

这就是为什么

您可能想先学习最基本的知识

这是我刚刚编写的一个示例

它启动一个只参与一个客户机的服务器,然后发送一个对象并终止

当用户(您)按enter键时,将创建一个新的客户端,它将连接到以前创建的服务器并读取服务器将发送的对象

这里不处理任何异常。只是为了让事情更简单,但这不是处理异常的方式

当您理解了这里的所有概念后,将更容易理解教程中的概念

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

public class SimpleServer implements Runnable { 

     // Creates the server, send a "date" and die.
    public void run() { 
        try {
            ServerSocket server = new ServerSocket( 8090 );
            Date creationDate = new Date();
            System.out.println("(Server) Server is ready " 
                                 + "and running at " + creationDate );

            Socket uniqueClient = server.accept();

            // We will write using this "chained" object.
            ObjectOutputStream out = new ObjectOutputStream( 
                                                 uniqueClient.getOutputStream());

            out.writeObject( creationDate );


            // close all, at this point forget about the exceptions.
            // this is lesson #1      
            out.close();

            uniqueClient.close();

            server.close();        

            System.out.println("(Server) The server is down");
        }catch( IOException ioe ) {}

     }

    public static void main ( String [] args ) throws IOException ,
                                                 ClassNotFoundException { 

         Thread serverThread = new Thread( new SimpleServer() );

         serverThread.start(); // start the server thread ... doh..

         System.out.println("(Client) Press enter when you want "+ 
                               " to connect to the server...");

         Scanner scanner = new Scanner( System.in );

         scanner.nextLine();

         Socket client = new Socket("localhost", 8090 );

         // Read from this object.
         ObjectInputStream in = new ObjectInputStream( client.getInputStream() );

         Date date = ( Date ) in.readObject();

         System.out.println("(Client) Current time is:          " + new Date() );
         System.out.println("(Client) Object read from server : " + date );

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

    }
}

我希望这能有所帮助。

如果您尝试调试器,它会告诉您问题出在哪里。(可能不是原因)

您遇到的问题是ObjectOutputStream写入一个标头,而ObjectInputStream读取该标头。您首先创建了ObjectInputStream,这意味着它试图读取一个永远不会写入的头

解决方案:始终首先创建ObjectOutputStream,并在创建ObjectInputStream之前刷新它。

只是一个提醒

使用ObjectOutputStream时,请记住它保留引用缓存。如果您写入一个对象,更改对象内容,然后再次发送相同的对象,您将获得重复的数据。例如:

List list = new ArrayList();
list.add("value1");
out.writeObject(list);
list.clear();
list.add("value2");
out.writeObject(list);
将在客户端生成两个字符串为“value1”的列表

为了避免这种情况,在多次写入同一对象引用时,必须调用reset方法来重置流缓存:

List list = new ArrayList();
list.add("value1");
out.writeObject(list);
out.reset();
list.clear();
list.add("value2");
out.writeObject(list);

问题在于创建流的顺序:

在本文中的服务器中(我假设您正在使用该服务器),当打开一个新连接时,服务器首先打开一个输入流,然后打开一个输出流:

public Connect(Socket clientSocket) {
 client = clientSocket;
 try {
  ois = new ObjectInputStream(client.getInputStream());
  oos = new ObjectOutputStream(client.getOutputStream());
 } catch(Exception e1) {
     // ...
 }
 this.start();
}
// open a socket connection
socket = new Socket("localhost", 2000);
// open I/O streams for objects
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
注释后的示例代码使用相反的顺序,首先建立输出流,然后建立输入流:

public Connect(Socket clientSocket) {
 client = clientSocket;
 try {
  ois = new ObjectInputStream(client.getInputStream());
  oos = new ObjectOutputStream(client.getOutputStream());
 } catch(Exception e1) {
     // ...
 }
 this.start();
}
// open a socket connection
socket = new Socket("localhost", 2000);
// open I/O streams for objects
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
但您的代码却以另一种方式运行:

server = new Socket(host, port);
in = new ObjectInputStream(server.getInputStream());
out = new ObjectOutputStream(server.getOutputStream());

建立输出流/输入流对将暂停,直到它们交换了握手信息,因此您必须匹配创建顺序。您可以通过交换示例代码中的第34行和第35行来实现这一点。

最好打开一个
outputStream
,因为输出流不会阻塞。然后,您就有了等待
流的输入流。在所有流之后,写入流并刷新它-
outputStream.flush()
以发送数据字节。您还需要另一端的一个方法来读取输入,无论它是简单的
inputStream.read()
,它将每个字节作为
char
的整数读取,还是使用
BufferedReader
扫描仪
。我已经使用了几乎所有可能的方法,但最有效的发送方法是
outputStream.write(String)
,它将
char
s序列作为
byte
s写入流,并读取
inputStream.read()
读取单个
char
。我希望这会有所帮助。

您需要取消注释它。哈,说真的,什么是编译错误?没有错误-它不能与我的未注释代码一起工作,我不明白为什么?注释后的代码有效-我刚刚将其分离,并将其放入实际对象中。。。这让我抓狂。发布的代码只包含客户端,所以它不需要编写对象。