Java Socket读和写意外行为 [英] Java Socket read and write unexpected behavior

查看:121
本文介绍了Java Socket读和写意外行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将文件从客户端传输到服务器时遇到问题。所以我做了一个简单的客户端和服务器代码在java使用套接字。我发现了一些意想不到的行为。我找不到为什么会这样。以下是代码



服务器端代码:

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

类服务器
{
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(); - 尝试包括此和删除这
outstr.write(buff2);
//inpstr.read();


fis.close();
inp.close();
ser.close();
} catch(IOException e){
// TODO自动生成的catch块
e.printStackTrace();
}
}
};

客户端代码:

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

class test
{
public static void main(String args [])throws UnknownHostException,IOException
{
Socket cnfcon = new Socket .0.1,9000);
OutputStream outstr = cnfcon.getOutputStream();
InputStream inpstr = cnfcon.getInputStream();
PrintWriter out = new PrintWriter(outstr,true);
BufferedReader inp = new BufferedReader(new InputStreamReader(inpstr));

文件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(开始客户端);

inpstr.read(buff,0,10);
disp(buff);
//outstr.write(1); - 尝试包括这个和删除这
inpstr.read(buff,0,10);
disp(buff);
//outstr.write(1); 1 - 虚拟值


fos.close();
out.close();
cnfcon.close();

}
public static void disp(byte buff [])
{
for(int i = 0; i <10; i ++)
.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()结果。


    I faced an issue while transferring file from client to server. So I did a simple client and server code in java using sockets. I found some unexpected behavior. I can't find why it happens so. Following is the code

    Server side code:

    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();
        }
      }
     };
    

    client side code:

    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();
    }
    };
    

    I am sending two buffers from server to client.

    Here I expect first buffer should come first and next for next time. But its unpredictable.

    Some times it works as expected. Some times it gets the 2nd buff for both time. Some times all bytes in the buffer are zero.

    I tried adding outstr.flush() before the message passing.

    Is there any other way to implement this?

    To be more clear, it seems client is not waiting for server to send or vice versa.

    The output is different every time.

    Suggestions are appreciated.

    解决方案

    The problems are at least two:

    1. You're ignoring the count returned by read(), and assuming it filled the buffer. It isn't obliged to do that. It isn't contracted to transfer more than one byte. You have to loop:

      while ((count = in.read(buffer)) > 0)
      {
          out.write(buffer, 0, count);
      }
      

    2. Data is disappearing into the buffered readers/writers/streams, and it is caused by using too many parts of the I/O stack. Don't use multiple readers, writers, and streams, on the same socket. Use a single output stream or writer and a single input stream or reader for the life of the socket. As you are writing binary data you shouldn't be using readers or writers at all.

    Contrary to other answers here, it isn't necessary to add flushes or sleeps in this code, as long as you close everything correctly, or to fiddle around with available() results either.

    这篇关于Java Socket读和写意外行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆