套接字传输文件

发布于 2024-10-06 06:30:41 字数 1156 浏览 1 评论 0原文

我有一个像这样的 Java 服务器类:

ServerSocket servsock = new ServerSocket(63456);
boolean read = false;
while (!read) {
    Socket sock = servsock.accept();
    int length = 1024;
    byte[] mybytearray = new byte[length];
    OutputStream os = sock.getOutputStream();
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
    while (true) {
    int i = bis.read(mybytearray, 0, mybytearray.length);
    if (i == 1) {
        break;
    }
    os.write(mybytearray, 0, mybytearray.length);
    os.flush();
    }
    sock.close();
    read = true;
}

` 而客户端是这样的:

Socket sock = new Socket("127.0.0.1", 63456);
byte[] mybytearray = new byte[1024];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("C:/tmp/NEWtmp.rar");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
while(bytesRead != -1 ) {
    bos.write(mybytearray, 0, bytesRead);
    bytesRead = is.read(mybytearray, 0, mybytearray.length);
}
bos.close();
sock.close();

有一个问题是:为什么循环不会在文件末尾停止? 第二个问题是,为什么这么慢?

I have a Java server class like this:

ServerSocket servsock = new ServerSocket(63456);
boolean read = false;
while (!read) {
    Socket sock = servsock.accept();
    int length = 1024;
    byte[] mybytearray = new byte[length];
    OutputStream os = sock.getOutputStream();
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
    while (true) {
    int i = bis.read(mybytearray, 0, mybytearray.length);
    if (i == 1) {
        break;
    }
    os.write(mybytearray, 0, mybytearray.length);
    os.flush();
    }
    sock.close();
    read = true;
}

`
And the client is like this:

Socket sock = new Socket("127.0.0.1", 63456);
byte[] mybytearray = new byte[1024];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("C:/tmp/NEWtmp.rar");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
while(bytesRead != -1 ) {
    bos.write(mybytearray, 0, bytesRead);
    bytesRead = is.read(mybytearray, 0, mybytearray.length);
}
bos.close();
sock.close();

One question is: Why the loop does not stop at the end of the file?
A second question would be, why is also so slow?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千纸鹤 2024-10-13 06:30:41

它不会停止,因为

if (i == 1) {

在您的服务器源中应该是

if (i == -1) {

或者,如果您想真正安全:

if (i <= 0) {

另外,您也可能会因这行代码而面临数据损坏的风险:

os.write(mybytearray, 0, mybytearray.length);

您应该将其更改为:

os.write(mybytearray, 0, i);

关于性能 - 移动 os.flush( ); 调用 while 循环之外。当您刷新网络流时,您将强制它将任何缓冲的数据分派到网络。这迫使网络层发送和确认 1024 字节 TCP 有效负载(当然,更大的以太网有效负载),这可能比 PMTU 小得多。仅当发送完数据或希望客户端立即接收缓冲数据时才需要刷新。从每次迭代中删除刷新调用将允许操作系统级网络缓冲区完成其工作,并将数据分段为尽可能少的数据包。

It does not stop because

if (i == 1) {

in your server source should be

if (i == -1) {

Or, if you want to be really safe:

if (i <= 0) {

Also, you risk data corruption with this line:

os.write(mybytearray, 0, mybytearray.length);

You should change this to:

os.write(mybytearray, 0, i);

On performance -- move the os.flush(); call to outside the while loop. When you flush a network stream, you are forcing it to dispatch any buffered data to the network. This is forcing the network layer to send and acknowledge 1024-byte TCP payloads (larger Ethernet payloads, of course) which is probably significantly smaller than your PMTU. You only need to flush when you are done sending data, or when you want the client to receive the buffered data now. Removing the flush call from each iteration will allow the OS-level network buffer to do its job, and segment the data into as few packets as possible.

勿忘初心 2024-10-13 06:30:41

第二个问题 - 您的客户端直接从原始套接字流读取字节。使用 BufferedInputStream/BufferedOutputStream 装饰器,这应该会提高性能:

服务器端

BufferedOutputStream os = new BufferedOutputStream(sock.getOutputStream());

客户端

BufferedInputStream is = new BufferedInputStream(sock.getInputStream());

原始流没有缓冲(AFAIK),因此如果需要,您必须手动添加缓冲。

Second question - your client reads bytes directly from the raw socket stream. Use the BufferedInputStream/BufferedOutputStream decorators, this should increase performance:

Server Side

BufferedOutputStream os = new BufferedOutputStream(sock.getOutputStream());

Client side

BufferedInputStream is = new BufferedInputStream(sock.getInputStream());

The raw streams are not buffered (AFAIK) so you have to add the buffering manually, if needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文