0

私はjava.netを勉強していて、somファイルを送信しようとしています。これが送信者コードです

public static final FilesGetter filesGetter = new FilesGetter();
    public static Socket s;
    public static File[] files;

    public static void main(String args[]) throws Exception{
        s = new Socket("localhost", 3128);

        while (true){
            try{
                files = filesGetter.getFilesList("/etc/dlp/templates/");
                Socket s = new Socket("localhost", 3128);
                args[0] = args[0]+"\n"+s.getInetAddress().getHostAddress()
                        +":"+s.getLocalPort();
                if (files != null){
                    for (int i = 0; i < files.length; i++){
                        InputStream is = new FileInputStream(files[i]);
                        byte[] message = IOUtils.toByteArray(is);
                        s.getOutputStream().write(message);

                        byte buf[] = new byte[64*1024];
                        int r = s.getInputStream().read(buf);
                        String data = new String(buf, 0, r);

                        System.out.println(data);
                    }
                }
            } catch(Exception e){
                System.out.println("init error: "+e);
            }
        }    
    }

そして、ここにレシーバーコードがあります:

public class Consumer extends Thread{

    public static Socket s;
    public String customerId;
    int num;
    public static final Filter filter = new Filter();
    public MimeParser mimeParser = new MimeParser(true);

    public Consumer(int num, final Socket s, final String customerId){
        this.num = num;
        this.s = s;
        this.customerId = customerId;

        setDaemon(true);
        setPriority(NORM_PRIORITY);
        start();
    }

    public static void receive(final String customerId){
        try {
            int i = 0;

            ServerSocket server = new ServerSocket(3128, 0, InetAddress.getByName("localhost"));

            System.out.println("server started");
            while (true){
                new Consumer(i, server.accept(), customerId);
                i++;
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    public void run(){
        try {
            InputStream is = s.getInputStream();
            OutputStream os = s.getOutputStream();

            byte buf[] = new byte[64*1024];
            int r = is.read(buf);

            if (r < 0)
                    return;
            ByteArrayInputStream bais = new ByteArrayInputStream(buf, 0, r);
            MessageInfo mi = mimeParser.parseMessages(bais);
            filter.getMessageAcceptability(mi.getPlainText(), customerId);
            s.close();
        } catch (Exception e){
            System.out.println("init error: " + e);
        }
    }
}

サーバー側でのデータの処理が完全に成功しておらず、処理コードの間違いを探す必要があるかどうかわからないため、データの整合性がわかりません (rabbitmq を使用しているときにうまく機能しました) またはクライアントサーバーコードで。また、どのバッファ サイズを選択する必要があるかもわかりません。

4

2 に答える 2

1

送信者側では、好きなだけ送信できます。64*1024 で構いません。send メソッドは、すべてのデータが配信されるまでループします。しかし、受信側では、ファイル全体が読み取られる前に read が返される可能性があります。反対側がソケットを閉じるまで、読み取りをループする必要があります。

このような場合、送信するデータ量を示す整数を事前に送信することをお勧めします。受信側は、そのバイト数が読み取られるまでループします。

例えば:

int ret=0;
int offset=0;
int BUFF_LEN=64*1024;
byte[] buffer = new byte[BUFF_LEN];
while ((ret = is.read(buffer, offset, BUFF_LEN - offset)) > 0)
{
    offset+=ret;
    // just in case the file is bigger that the buffer size
   if (offset >= BUFF_LEN) break;
}
于 2013-07-17T15:48:57.690 に答える
0

送信側と受信側の両方で SHA-1 のようなチェックサムを計算する必要があります。一致する場合は、伝送エラーはなかったと見なすことができます。あなたの質問は、実際にはプロトコルの質問です。

独自の整合性チェックを実装するよりもはるかに簡単で実用的なソリューションは、SSL プロトコルを使用することです。これにより、完全性が確認された送信が提供されます。

于 2013-07-17T15:46:25.010 に答える