如何在Java套接字编程中实现从客户端到服务器的连续交互 [英] How to make continuous interaction from client to server in Java socket programming

查看:104
本文介绍了如何在Java套接字编程中实现从客户端到服务器的连续交互的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在Java套接字编程中从客户端到服务器进行连续交互。在我的程序中,我在目录中有许多文件夹,即)F://读取,我正在从文件夹传输文件夹从客户端到服务器。当第一次请求时,一个文件夹从客户端转移到服务器,当它再次到客户端发送另一个文件夹时,它一直说异常,java.net.SocketException:Socket在ClientProgram的write()方法中关闭我调用socket.getOutputStream()。所以请告诉我如何解决这个问题。我想我想为每次传输使用线程,所以请告诉我必须使用哪个来运行这个。非常感谢。

How to make continuous interaction from client to server in Java socket programming. Here in my program i have many folders in a directory ie) F://read and i am transferring folders with files from client to server. when at first request, one folder is transferred to the server from client and when it comes again to the client to send an another folder it's keep saying exception, java.net.SocketException: Socket is closed in the write() method of ClientProgram where i call socket.getOutputStream(). So please tell me how to resolve this problem. I think i want to use thread for each transmission, so please tell where i have to use to run this fine. Very much thank's.

客户代码:

每次转发方法和写入方法将数据从客户端传递到服务器。和listf(String directoryName)方法递归运行文件和文件夹,当它找到它调用的文件夹的forward()和write()方法时。 forward()是传递特定文件夹的目录路径,write()方法是在客户端写入所有文件,并且每次都通过listf(String directoryName)传递给服务器。这个方法第一次运行正常。当第二次再次调用write()方法时,会给出java.net.SocketException:Socket关闭。为什么会发生。

At each time forward method and write method passing data's from client to server. and listf(String directoryName) method running recursively for files and folders, when it finds folder it call's forward()and write() method. the forward() is to pass the directory path of the particular folder and write() method is to write all files here in client and passes to server at each time by the listf(String directoryName). at first time this method running fine. when at the second time again it calls write() mothod, there its giving java.net.SocketException: Socket is closed.why its happening.

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ClientProgram extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public ClientProgram() {
        super();
    }
    Socket socket;
    ClientProgram clientProgram;
    String hostDomain = "192.168.1.19";
    int port = 5855;
    BufferedOutputStream bos;
    DataOutputStream dos;
    BufferedInputStream bis;
    FileInputStream fis;
    PrintStream pr;
    BufferedReader gt;
    List<File> resultList;

    public static listf(String directoryName) throws IOException {
        try {
            File directory = new File(directoryName);
            resultList = new ArrayList<File>();
            // get all the files from a directory
            File[] fList = directory.listFiles();
            resultList.addAll(Arrays.asList(fList));
            for (File file : fList) {
                if (file.isFile()) {
                    System.out.println("file: " + file.getAbsolutePath());
                } else if (file.isDirectory()) {
                    String pathtomake = file.getAbsolutePath();
                    System.out.println("folder now: " + pathtomake);
                    forward(pathtomake);
                    write(pathtomake);
                    System.out.println("folder: " + file.getAbsolutePath());
                    listf(file.getAbsolutePath());

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                bis.close();
            }
            if (dos != null) {
                dos.close();
            }
            if (fis != null) {
                fis.close();
            }
        }
        return resultList;
    }

    public void write(String rec) throws IOException {
        try {
            System.out.println("rr");
            bos = new BufferedOutputStream(socket.getOutputStream());
            dos = new DataOutputStream(bos);
            File file1 = new File(rec);
            File[] fil_Files_list = file1.listFiles();
            dos.writeInt(fil_Files_list.length);
            System.out.println("file will ..");
            for (File file : fil_Files_list) {
                long length = file.length();
                dos.writeLong(length);
                String name = file.getName();
                dos.writeUTF(name);
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                System.out.println("writin..");
                int theByte = 0;
                while ((theByte = bis.read()) != -1) {
                    bos.write(theByte);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

    public void forward(String drc) throws UnknownHostException, IOException {
        boolean b = socket.isConnected();
        System.out.println("Socket Is active or not: " + b);
        pr = new PrintStream(socket.getOutputStream());
        pr.println(drc);
        gt = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String tm = gt.readLine();
        System.out.print(tm);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        socket = new Socket(hostDomain, port);
        String directory = "F://read";
        listf(directory);

    }

}

服务器代码:

这是我的服务器代码接受,用于接收带文件的文件夹。这里我从客户端方法使用BufferedReader接收名为forward()并添加到detination路径的文件夹路径,即d)// save。之后,我将所有文件从名为write()的客户端方法写入特定文件夹。

This is my server code accept to receive folders with files. here i am receiving folder path using BufferedReader from client method called forward() and adding to the detination path ie)d://save. after that i am writing all the files to the particular folder from client method called write().

import java.io.*;
import java.net.*;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServerProgram extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public ServerProgram() {
        super();
        // TODO Auto-generated constructor stub
    }

    BufferedReader ed;
    PrintStream pr;
    BufferedInputStream bis;
    DataInputStream dis;
    FileOutputStream fos;
    BufferedOutputStream bos;
    Socket socket;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            System.out.println(1);
            ServerSocket serverSocket = new ServerSocket(5792);
            System.out.println(2);
            socket = serverSocket.accept();

            ed = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String tmp = ed.readLine();
            System.out.print("I Recieved :" + tmp);
            pr = new PrintStream(socket.getOutputStream());
            String str = "Yup I got it !!";
            pr.println(str);
            int g = tmp.indexOf("\\");
            String di = tmp.substring(g);
            String dirPath = "D://save//" + di;
            System.out.println(dirPath);
            File file = new File(dirPath);
            JavaHeapMemory();

            if (file.exists() || file.mkdirs()) {
                bis = new BufferedInputStream(socket.getInputStream());
                dis = new DataInputStream(bis);
                int filesCount = dis.readInt();
                File[] files = new File[filesCount];
                for (int i = 0; i < filesCount; i++) {
                    long fileLength = dis.readLong();
                    String fileName = dis.readUTF();
                    System.out.println("name of the file: " + fileName);
                    files[i] = new File(dirPath + "/" + fileName);
                    FileOutputStream fos = new FileOutputStream(files[i]);
                    BufferedOutputStream bos = new BufferedOutputStream(fos);
                    for (int j = 0; j < fileLength; j++) {
                        bos.write(bis.read());
                    }

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                bos.close();
            }
            if (dis != null) {
                dis.close();
            }
            try {
                socket.close();
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }

    public void JavaHeapMemory() {
        long heapSize = Runtime.getRuntime().totalMemory();
        System.out.println("Heap Size = " + heapSize);
    }
}

异常:

            java.net.SocketException: Socket is closed
                at java.net.Socket.getOutputStream(Unknown Source)
                at pack.ClientProgram.forward()

在上面的客户端程序中,我用来递归地将文件夹传输到服务器。但它不是从客户端连续运行到服务器。所以请告诉我这样做的方法。我非常感谢。

In this above client program i used to transfer folders to the server recursively. but its not running in continuously from client to server.so please tell me the way to do this. i am very much thankful.

推荐答案

你可以混合使用文本和二进制文件而不会产生混淆。

You canot mix text and binary without the likelihood of confusion.

  ed = new BufferedReader(new InputStreamReader(socket.getInputStream()));

这意味着BufferedReader可以读取尽可能多的数据,而不仅仅是您要求的数据。

This means the BufferedReader can read as much data as it likes, not just how much you ask for.

  bis = new BufferedInputStream(socket.getInputStream());

这将开始在BufferedReader未读取的某个随机点读取二进制数(不是你的数量)要求)

This will start reading binary at some random point that the BufferedReader didn't read (not the amount you asked for)

简而言之,除非你真的知道自己在做什么,否则只能使用二进制文本或文本。

In short, only use binary or text for a stream unless you really know what you are doing.

您的计划

while ((theByte = bis.read()) != -1)
      bos.write(theByte);

这意味着,请读到流的结尾。这也意味着它将读取连接关闭前发送的所有数据。

This means, read until the end of the stream. It also means it will read all data sent until the connection is closed.

如果要在同一个流中发送多个文件,接收器需要另一种方式知道文件何时结束。最简单的方法是首先发送文件大小,让接收者只读取那么多数据。

If you want to send multiple files in the same stream, you need another way for the receiver to know when the file ended. The simplest approach is to send the file size first, and have the reciever only read that much data.

BTW一次读取一个字节非常慢。我建议你读一个大小为4KB的字节[]。

BTW reading one byte at a time is very slow. I suggest you read into a byte[] of say size 4KB.

这篇关于如何在Java套接字编程中实现从客户端到服务器的连续交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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