无法通过套接字

时间:2016-10-12 09:03:02

标签: java sockets outputstream

在将此标记为可能重复之前,请先阅读一次,因为我无法找到任何答案。我正在学习Socket编程并使用套接字创建非常基本的服务器 - 客户端文件传输程序。 这是我的服务器模块:

import java.io.*;
import java.net.*;
import static java.lang.System.out;

public class ServerMain {
    public static void main(String[] args) {
    int PORT=13267;
    ServerSocket servSocket;
    Socket client;
    File source=new File("E:/Styles of Beyond.wav");;
    BufferedInputStream bis;
    BufferedReader br;
    String s="";
    InputStream is;
    byte[] byteBuffer=new byte[10240];
    OutputStream os;
    int count=0;

    try{

        servSocket=new  ServerSocket(PORT);
        out.println("Server running on port: "+PORT+", waiting for client...");
        client=servSocket.accept();
        client.setKeepAlive(true);
        out.println("Client: "+client.getRemoteSocketAddress()+" connected. Sending file...");
        bis=new BufferedInputStream(new FileInputStream(source));
        os=client.getOutputStream();
        is=client.getInputStream();

        while((count=bis.read(byteBuffer))>0){
            os.write(byteBuffer, 0, count);
        }

        out.println("Waiting for confirmation from client...");
        br=new BufferedReader(new InputStreamReader(is));
        if(br.readLine()=="Done")
            out.println("Done.");
        else
            out.println("Couldn't get confirmation from server.");
    }

    catch(Exception e)
    {
        e.printStackTrace();
    }
}
}

客户端模块:

import static java.lang.System.out;
import java.io.*;
import java.net.*;

public class ClientMain {

    public static void main(String[] args) {
        int SERV_PORT=13267;
        Socket server;
        File destination=new File("E:/copy.wav");
        byte[] byteBuffer=new byte[10240];
        InputStream is;
        OutputStream os;
        BufferedWriter bw;
        int count=0;

        try{
            out.println("Tyring to connect to server...");
            server=new Socket("localhost",SERV_PORT);
            out.println("Connected to server: "+server.getRemoteSocketAddress());
            is=server.getInputStream();
            os=server.getOutputStream();
            out.println("Receiving data...");
            BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(destination));

            while((count=is.read(byteBuffer))>0){
                bos.write(byteBuffer, 0, count);
            }
            bw=new BufferedWriter(new OutputStreamWriter(os));
            bw.write("Done");
            bw.newLine();
            out.println("Data successfully written to copy.wav");
        }
        catch(Exception e){
            e.printStackTrace();
        }
}
}

代码工作,甚至文件copy.wav都是正确创建的,但是在客户端的操作系统上写完后,服务器就会卡在"等待来自客户端的确认...",并且客户端是卡在"接收数据......"。我尝试在客户端使用PrintWriter而不是BufferedWriter,并且还尝试在os上编写单个字节,并在服务器端检查该字节是否为文件接收确认,但似乎没有任何效果,客户端没有发送任何内容。我注意到的一件事是在服务器上调用is.ready()总是返回false。

如果我删除了与发送和接收客户端上的文件确认相关的所有代码。服务器,客户端程序生成SocketException:连接重置,因为现在服务器没有等待客户端完成其is.read()任务,并在使用os.write()完成写入后立即关闭连接,创建copy.wav,其部分数据的大小小于原始数据。我该怎么做呢?

P.S:我知道我没有关闭流并正确处理异常,但这似乎不是问题。

1 个答案:

答案 0 :(得分:2)

冲洗它!

https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html#flush()

打电话后

        bw.write("Done");
        bw.newLine();

操作系统正在等待更多,因此它可以有效地将数据发送到一大块。

此外,您可以在其上设置TCP_NODELAY,但通常应该让操作系统执行此操作,因为在大多数情况下,它比您更了解发送数据的最佳方式。

How does TCP_NODELAY affect consecutive write() calls?