[英]Java Socket read and write unexpected behavior
从客户端到服务器传输文件时遇到问题。 所以我在Java中使用套接字做了一个简单的客户端和服务器代码。 我发现了一些意外的行为。 我找不到为什么会这样。 以下是代码
服务器端代码:
import java.io.*;
import java.net.*;
class Server
{
public static void main(String args[])
{
ServerSocket ser;
try {
ser=new ServerSocket(9000);
Socket cnfcon=ser.accept();
OutputStream outstr=cnfcon.getOutputStream();
InputStream inpstr=cnfcon.getInputStream();
PrintWriter out=new PrintWriter(outstr,true);
BufferedReader inp=new BufferedReader(new InputStreamReader(inpstr));
File f=new File("test.txt");
InputStream fis= new FileInputStream(f);
long size=f.length();
System.out.println("Start Server");
out.println(f.getName());
out.println(size);
byte[] buff1=new byte[]{0,1,2,3,4,5,6,7,8,9};
byte[] buff2=new byte[]{7,1,2,3,8,5,6,7,8,9};
outstr.write(buff1);
//inpstr.read(); -- tried including this and removing this
outstr.write(buff2);
//inpstr.read();
fis.close();
inp.close();
ser.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
客户端代码:
import java.io.*;
import java.net.*;
class test
{
public static void main(String args[]) throws UnknownHostException, IOException
{
Socket cnfcon=new Socket("127.0.0.1",9000);
OutputStream outstr=cnfcon.getOutputStream();
InputStream inpstr=cnfcon.getInputStream();
PrintWriter out=new PrintWriter(outstr,true);
BufferedReader inp=new BufferedReader(new InputStreamReader(inpstr));
File f=new File(inp.readLine()+"t"); //"t" - dummy
f.createNewFile();
FileOutputStream fos=new FileOutputStream(f);
int size=Integer.parseInt(inp.readLine());
byte buff[]=new byte[1024];
System.out.println("Start Client");
inpstr.read(buff, 0, 10);
disp(buff);
//outstr.write(1); -- tried including this and removing this
inpstr.read(buff, 0, 10);
disp(buff);
//outstr.write(1); 1 - dummy value
fos.close();
out.close();
cnfcon.close();
}
public static void disp(byte buff[])
{
for(int i=0;i<10;i++)
System.out.print(buff[i]);
System.out.println();
}
};
我正在从服务器到客户端发送两个缓冲区。
在这里,我希望第一个缓冲区应该排在第一位,下一次要在下一个缓冲区。 但其变化莫测。
有时它会按预期工作。 有时它会同时获得第二个buff。 有时,缓冲区中的所有字节均为零。
我尝试在消息传递之前添加outstr.flush()。
还有其他方法可以实现吗?
更明确地说,似乎客户端没有在等待服务器发送,反之亦然。
每次输出都不同。
建议表示赞赏。
问题至少有两个:
您将忽略read()
返回的计数,并假设它已填充缓冲区。 它没有义务这样做。 传输的字节数不超过一个字节。 您必须循环:
while ((count = in.read(buffer)) > 0) { out.write(buffer, 0, count); }
数据消失在缓冲的读取器/写入器/流中,这是由于使用了I / O堆栈的过多部分所致。 不要在同一套接字上使用多个读取器,写入器和流。 在套接字的生存期内,请使用单个输出流或写入器以及单个输入流或读取器。 在编写二进制数据时,您根本不应该使用读取器或写入器。
与这里的其他答案相反,只要正确地关闭所有内容,或者摆弄available()
结果,就不必在代码中添加刷新或休眠。
尝试在客户端收到缓冲区时在客户端添加Thread.sleep()
吗? 不知道是否会工作。
让我猜猜,您正在使用Microsoft Windows?
首先将数据分成小块(比如说1kb),但是您已经在执行此操作,然后在读取和写入循环中都睡了一点。 写入后在可能的情况下调用flush,并确保未读超过输入流。availible()
您的代码应该可以在其他操作系统上正常工作,而无需修改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.