Java 在套接字上写入大字符串时出错?

Java 在套接字上写入大字符串时出错?,java,sockets,tcp,bufferedreader,bufferedwriter,Java,Sockets,Tcp,Bufferedreader,Bufferedwriter,各位朋友好, 我试图通过套接字连接发送一个长字符串,但我将它们分为两部分,因此在执行进程时出错 在客户端,我正在发送文件 BufferedWriter bufferedOut = null; BufferedReader in = null; socket = new Socket("192.168.0.15",4444); bufferedOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); in

各位朋友好,

我试图通过套接字连接发送一个长字符串,但我将它们分为两部分,因此在执行进程时出错

在客户端,我正在发送文件

BufferedWriter bufferedOut = null;
BufferedReader in = null;
socket = new Socket("192.168.0.15",4444);
bufferedOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

bufferedOut.write(xmlInString, 0, xmlInString.length());

/**
* wait for response
*/

byte[] buf = new byte[10000];
int actualNumberOfBytesRead = socket.getInputStream().read(buf);
String responseLine = new String(buf, 0, actualNumberOfBytesRead);
在服务器中

 BufferedReader in = null;
 PrintWriter out = null;
 in = new BufferedReader(new InputStreamReader(client.getInputStream()));
 out = new PrintWriter(client.getOutputStream(), true);

//get the input
 byte[] buf = new byte[10000];
 int actualNumberOfBytesRead = client.getInputStream().read(buf);
 line = new String(buf, 0, actualNumberOfBytesRead);
 //send back
 out.println(result);
我怎样才能把我的绳子作为一部分?你能告诉我我在密码上的错误在哪里吗


谢谢大家

您需要一个循环来重复读取输入流,每次都将读取的数据连接在一起,直到到达字符串的末尾

编辑-更详细一点。如果您希望传输多个这样的字符串/文件,请参阅@arnaud的答案。如果您希望发送一个大字符串,则:

  • 在发送方,创建输出流,发送数据(正如您所做的),然后不要忘记再次关闭流(这也将执行刷新,以确保数据通过线路发送,并通知另一端不再有数据)

  • 在接收方站点上,在循环中读取数据,直到输入流结束(read(buf)返回-1),每次将数据连接到一个大缓冲区中,然后关闭输入流


  • 另外,请阅读我关于以字节而不是字符串形式发送文件的评论。这对于XML文件尤其重要,因为XML文件具有相当特殊的编码检测规则。

    使用TCP套接字时,您正在处理“流”。也就是说,默认情况下消息之间没有界限。通过这样做,您可能会阅读一条消息的一部分,或者更糟糕的是,您可能会阅读多条消息

    最常见的方法是对消息进行分隔。您可以使用DataInputStream/DataOutputStream将字符串编码为字节,并使用第一个字节指示其长度。这样,它就知道应该在接收端读取多少字节

        DataOutputStream out = null;
        DataInputStream in = null;
        Socket socket = new Socket("192.168.0.15",4444);
        out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
        in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
    
        out.writeUTF(xmlInString);
        out.flush(); // to ensure everything is sent and nothing is kept in the buffer.
    
        // wait for response
    
        String responseLine = in.readUTF();
    
    然后,相应地调整服务器代码

    当使用带套接字的
    缓冲
    输出时(出于性能原因,建议这样做),建议在编写消息后
    刷新()
    ,以确保所有内容都通过网络发送,并且缓冲区中没有任何内容


    您最初的问题可能是因为您的邮件需要多个TCP/IP数据包,并且在服务器中,您只读取刚到达的第一个数据包。

    您是指(在服务器中)而(in.line!=null){line=line+in.line}?基本上是的,不过最好使用StringBuilder连接数据。注意:如果您发送的只是文件,我建议您将其作为字节发送,而不是字符串发送,除非您非常确定您正确地读取了它。否则,您将遇到编码问题(例如,虽然它实际上是一个UTF-8文件,但客户端将其读取为ISO xxx)。这样做,套接字在尝试读取更多字节时将简单地阻塞。(它不知道流何时结束……除非你在另一边关闭它……无论如何,这很糟糕)我试着像我写的那样在while循环中逐行阅读,但它从来没有进入while循环!它总是在等待(in.line!=null)有什么问题@阿诺:这完全取决于是否打算发送多个字符串/文件。如果只需要一个文件传输(问题没有另外指出),那么发送方执行打开/发送/关闭操作,接收方执行读取操作直到关闭该流是完全可以接受的。阻塞使得代码更加容易。