JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java SE 討論區  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友   
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 GZIPOutputStream...? [精華]
timothy





發文: 24
積分: 0
於 2003-08-18 19:25 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
這個GZIPOutputStream是用來壓縮的沒錯,不過大家有沒有試過把它用在網路的資料傳送上呢?我的問題是這樣子的,
EX:傳送端 GZIPOutputStream gzOut = new GZIPOutputStream(socket.getOutputStream);
接收端 GZIPInputStream gzIn = new GZIPInputStream(socket.getInputStream);

但是傳送端由於GZIPOutputStream的buffer原因,部份資料會保留在buffer中,不會傳送出去!我試過了,flush()的方法不行!也試過,finish()的方法,雖然確實是會將buffer中的資料寫入底層的OutputStream,但是接收端接收完資料後便會一直接收到-1(也就是 int size = gzIn.read(byte[]);,size會一直為-1),不知道大家有沒有這方面的經驗,供參考,解答一下!謝!


reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:timothy]
browser

戀香

版主

發文: 3570
積分: 1
於 2003-08-18 19:28 user profilesend a private message to usersend email to browserreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
timothy wrote:
這個GZIPOutputStream是用來壓縮的沒錯,不過大家有沒有試過把它用在網路的資料傳送上呢?我的問題是這樣子的,
EX:傳送端 GZIPOutputStream gzOut = new GZIPOutputStream(socket.getOutputStream);
接收端 GZIPInputStream gzIn = new GZIPInputStream(socket.getInputStream);

但是傳送端由於GZIPOutputStream的buffer原因,部份資料會保留在buffer中,不會傳送出去!我試過了,flush()的方法不行!也試過,finish()的方法,雖然確實是會將buffer中的資料寫入底層的OutputStream,但是接收端接收完資料後便會一直接收到-1(也就是 int size = gzIn.read(byte[]);,size會一直為-1),不知道大家有沒有這方面的經驗,供參考,解答一下!謝!


try ...
http://www.javaworld.com.tw/jute/post/view?bid=20&id=480&sty=1&tpg=1&age=0

PS.不知對 timothy 兄 .. 有沒有幫助 ... Tongue


reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:timothy]
timothy





發文: 24
積分: 0
於 2003-08-18 21:58 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
謝了!無論如何還是先感謝你,版主!

reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:timothy]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-08-20 22:47 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
timothy wrote:
這個GZIPOutputStream是用來壓縮的沒錯,不過大家有沒有試過把它用在網路的資料傳送上呢?我的問題是這樣子的,
EX:傳送端 GZIPOutputStream gzOut = new GZIPOutputStream(socket.getOutputStream);
接收端 GZIPInputStream gzIn = new GZIPInputStream(socket.getInputStream);

但是傳送端由於GZIPOutputStream的buffer原因,部份資料會保留在buffer中,不會傳送出去!我試過了,flush()的方法不行!也試過,finish()的方法,雖然確實是會將buffer中的資料寫入底層的OutputStream,但是接收端接收完資料後便會一直接收到-1(也就是 int size = gzIn.read(byte[]);,size會一直為-1),不知道大家有沒有這方面的經驗,供參考,解答一下!謝!


我的作法是傳送端把要傳送的 data 寫入 GZIPOutputStream 後,call finish method,然後拿底層的 output stream 重建一個 GZIPOutputStream,以便傳送下一批資料。

而接收端以 available method 的傳回值判斷傳送端是否已傳完一批資料(available 傳回 0),是的話處理資料,然後拿底層的 input stream 重建一個 GZIPInputStream 處理下一批資料;如果傳送端沒傳完(available 傳回 1),接收端就一直接收資料。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:GZIPOutputStream...? [Re:timothy]
kotoway





發文: 30
積分: 2
於 2003-08-21 00:10 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan 兄:
可不可以把你的source code分享一下泥!!
謝謝


reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:kotoway]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-08-21 14:48 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
kotoway wrote:
Duncan 兄:
可不可以把你的source code分享一下泥!!
謝謝


隨手寫一個,不講究畫面和架構。
許多壓縮演算法都需要一整個 data(sample) 去作演算得到壓縮後的資料串與額外的資訊(解壓縮用),沒辦法像一般的 IO stream 來操作,不似 IO stream 一端傳送(壓)資料,另一端就可以接收(解)多少資料,必須要資料一批接著一批遞送,每一批使用一個壓縮工具。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//MsgReceiver.java
package com.jsptw.example;
 
import java.awt.BorderLayout;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.zip.GZIPInputStream;
 
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.JTextComponent;
 
public class MsgReceiver implements Runnable{
 
  public static void main(String[] args)
  {
    int port = (args.length > 0)? Integer.parseInt(args[0]) : 5271;
    JFrame frm = new JFrame("Message receiver");
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    JTextArea txt = new JTextArea(15, 50);
    txt.setEditable(false);
    JScrollPane pane = new JScrollPane(txt);
    frm.getContentPane().add(pane, BorderLayout.CENTER);
    frm.pack();
    frm.show();
    
    Thread thd = new Thread(new MsgReceiver(port, txt), "MsgReceiver");
    thd.setDaemon(true);
    thd.start();
  }
 
  public MsgReceiver(int port, JTextComponent comp)
  {
    txtComp = comp;
    this.port = port;
  }
  
  public void run()
  {
    ServerSocket server;
    Socket soc;
    GZIPInputStream istream;
    try{
      server = new ServerSocket(port);
      soc = server.accept();
      istream = new GZIPInputStream(soc.getInputStream());
      byte[] buf = new byte[52100];
      int total = 0;
      while (true)
      {
        if (istream.available() > 0){
          int n = istream.read(buf, total, buf.length - total);
          total += n;
        }
        else{ // Data block is transmitted completely.
          txtComp.setText(new String(buf, 0, total, "UTF-8"));
          total = 0;
          istream = new GZIPInputStream(soc.getInputStream());
        }
      }
    }
    catch (Exception e){
      e.printStackTrace();
    }
  }
  
  private JTextComponent txtComp;
  private int port;
}


執行:
java com.jsptw.example.MsgReceiver [port=5271]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//MsgSender.java
package com.jsptw.example;
 
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.zip.GZIPOutputStream;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
 
public class MsgSender extends JFrame implements ActionListener {
 
  public MsgSender(String host, int port) throws UnknownHostException, IOException
  {
    super("Message sender");
    
    socket = new Socket(host, port);
    initComponents();
    
  }
 
  public void actionPerformed(ActionEvent e)
  {
    if (e.getActionCommand().equals(COMMAND_SEND)){
      try {
        GZIPOutputStream ostream = new GZIPOutputStream(
          socket.getOutputStream()
        );
        String msg = txt.getText() + "\n";
        ostream.write(
          msg.getBytes("UTF-8")
        );
        ostream.finish();
      }
      catch (IOException e1) {
        e1.printStackTrace();
      }
    }
    else if(e.getActionCommand().equals(COMMAND_CLEAR)){
      txt.setText(null);
      send.doClick();
    }
  }
 
  public static void main(String[] args) throws IOException
  {
    if (args.length < 2){
      printUsage();
      return;
    }
    
    JFrame frm = new MsgSender(args[0], Integer.parseInt(args[1]));
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frm.pack();
    frm.show();
  }
  
  public static void printUsage()
  {
    System.out.println(
      "Usage:\n" +
      "java MsgSender destination_host port\n\n" +
      "destination_host - receiver host location.\n" +
      "port - the port used to setup connection.\n"
    );
  }
 
  public void dispose()
  {
    super.dispose();
    if (!socket.isClosed()){
      try {
        socket.close();
      }
      catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  
  private void initComponents()
  {
    Container con = getContentPane();
    
    send = new JButton(COMMAND_SEND);
    send.addActionListener(this);
    JButton clear = new JButton(COMMAND_CLEAR);
    clear.addActionListener(this);
 
    JPanel tool = new JPanel(new GridLayout(1, 0, 5, 5));
    tool.add(send); tool.add(clear);
    con.add(tool, BorderLayout.SOUTH);
    
    txt = new JTextArea(15, 50);
    con.add(new JScrollPane(txt), BorderLayout.CENTER);
  }
  
  private JTextArea txt;
  private Socket socket;
  private static String COMMAND_SEND = "送出資料";
  private static String COMMAND_CLEAR = "清除內容";
  private JButton send;
}


執行:
java com.jsptw.example.MsgSender destination_host port


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:GZIPOutputStream...? [Re:timothy]
kotoway





發文: 30
積分: 2
於 2003-08-21 21:16 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
那如果我是先把全部資料壓後,再送....這樣有可以嗎??

reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:kotoway]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-08-21 21:46 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
kotoway wrote:
那如果我是先把全部資料壓後,再送....這樣有可以嗎??


當然可以。不過你所謂的全部資料是指接收端接完就要 close socket 了嗎?
如果是這樣的話,你怎麼會因為接收端 read method 傳回 -1 而困擾呢?傳回 -1 表 EOF 不就是資料傳送完畢嗎?

如果情況是資料總量不確定,有資料就送過去,為了讓接收端能有機會處理資料,傳送端應該在傳送適當量後就 invoke 一次 finish method。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:GZIPOutputStream...? [Re:timothy]
76409944





發文: 25
積分: 0
於 2003-08-22 00:50 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan先生,我測試過您的程式了,很開心真的可以跑耶,真謝謝你,但是我有一個疑問哦,請問一下那個server端的程式是不是一直在跑while的迴圈啊,這樣不是會無窮迴圈嗎?但為什麼我看cpu並沒有一直在吃資源啊(可能我問的問題有點笨,但我真的想要知道),謝謝您•

reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:76409944]
timothy





發文: 24
積分: 0
於 2003-08-22 03:47 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
76409944 wrote:
Duncan先生,我測試過您的程式了,很開心真的可以跑耶,真謝謝你,但是我有一個疑問哦,請問一下那個server端的程式是不是一直在跑while的迴圈啊,這樣不是會無窮迴圈嗎?但為什麼我看cpu並沒有一直在吃資源啊(可能我問的問題有點笨,但我真的想要知道),謝謝您•


嗯,先感謝Duncan的回覆,這個方式確實是不錯用!

Server在的那個while像是傾聽client端的連線(socket = ServerSocket.accept()),之所以不會CPU 100%是因為執行到這一行時是停在那邊等待的,而不是重覆的反覆執行。
像是接收資料也是(int n = socket.getInputStream.read(byte[])),也都是只停著等待,有資料或client連線時才會繼續下面的動作。


reply to postreply to post
作者 Re:GZIPOutputStream...? 問個問題!! 上面那個方我用不出!! [Re:timothy]
kotoway





發文: 30
積分: 2
於 2003-08-22 06:27 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
注意我打****的地方,有疑問!!!
public OutputStream gzout;
public Socket socket; //這樣算是全域變數吧!!

//按登入
public boolean connectserver(String ip){//檢驗是否連線上server
try{
serverip=ip;
socket=new Socket(serverip,imgport);****
gzout=socket.getOutputStream(); ****如果我寫在這裡圖片就送不出去,但是如果寫在下面*號那邊就可以送出去,天大的疑問????
因為我不是登入後就要送圖片,那如果兩個地方都寫,不就登入兩次了嗎??
return socket.isConnected();
}
catch (IOException e){
return socket.isConnected();
}
}
//按播放, .....我只會用這種笨方法而且成功
public void sentimggz(){
try{

filein=new FileInputStream("c:\\comic16.jpg");
int flen=filein.available();
System.out.println("flen"+flen);
int times=flen/1024;
System.out.println("times"+times);
int remain=flen%1024;
System.out.println("remain"+remain);
System.out.println("Sending length to Server");

// socket=new Socket("192.168.0.9",imgport); ****
// gzout=socket.getOutputStream(); ****
for(int i=0;i<times;i++){
byte array_1[]=new byte[1024];

if(filein.read(array_1,0,1024)!=1024){
System.out.println("error");
}
System.out.println(array_1);
gzout.write(array_1);
gzout.flush();
}
if(remain!=0){
byte array_1[]=new byte[remain];

if(filein.read(array_1,0,remain)!=remain)
System.out.println("error......");
gzout.write(array_1);

gzout.flush();

System.out.println("sened2 "+remain);
}
gzout.close();
}

catch(FileNotFoundException e){
System.err.println("file not fount");
}
catch(IOException e){
System.out.println("test error");
}

}


reply to postreply to post
作者 Re:GZIPOutputStream...? 問個問題!! 上面那個方我用不出!! [Re:kotoway]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-08-22 12:49 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
kotoway wrote:
注意我打****的地方,有疑問!!!


我大膽假設,要不是 connectserver method 的 IP 有錯,就是你根本沒有 invoke 過 connectserver method。Black Eye

從這些程式片段,真的看不出來怎麼回事!


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:GZIPOutputStream...? [Re:timothy]
kotoway





發文: 30
積分: 2
於 2003-08-22 13:09 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
因為如果我寫在上面的****的地方 ,一直顯示NullPointException 在gzout.write(array_1);
再問,照道理講登入一次就可以了嗎?


reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:timothy]
timothy





發文: 24
積分: 0
於 2003-08-22 16:24 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
嗯,kotoway說的可能是對的。你要不要再多貼一些其它的部份,大家一起來幫你看看,因為這樣看不出來。

另外Client只要進行一次與Server連線成功後,只要過程中沒有錯誤或關閉它,是可以一直互相傳送資料的。


reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:Duncan]
timothy





發文: 24
積分: 0
於 2003-08-22 17:55 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
隨手寫一個,不講究畫面和架構。
許多壓縮演算法都需要一整個 data(sample) 去作演算得到壓縮後的資料串與額外的資訊(解壓縮用),沒辦法像一般的 IO stream 來操作,不似 IO stream 一端傳送(壓)資料,另一端就可以接收(解)多少資料,必須要資料一批接著一批遞送,每一批使用一個壓縮工具。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//MsgReceiver.java
package com.jsptw.example;
 
import java.awt.BorderLayout;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.zip.GZIPInputStream;
 
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.JTextComponent;
 
public class MsgReceiver implements Runnable{
 
  public static void main(String[] args)
  {
    int port = (args.length > 0)? Integer.parseInt(args[0]) : 5271;
    JFrame frm = new JFrame("Message receiver");
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    JTextArea txt = new JTextArea(15, 50);
    txt.setEditable(false);
    JScrollPane pane = new JScrollPane(txt);
    frm.getContentPane().add(pane, BorderLayout.CENTER);
    frm.pack();
    frm.show();
    
    Thread thd = new Thread(new MsgReceiver(port, txt), "MsgReceiver");
    thd.setDaemon(true);
    thd.start();
  }
 
  public MsgReceiver(int port, JTextComponent comp)
  {
    txtComp = comp;
    this.port = port;
  }
  
  public void run()
  {
    ServerSocket server;
    Socket soc;
    GZIPInputStream istream;
    try{
      server = new ServerSocket(port);
      soc = server.accept();
      istream = new GZIPInputStream(soc.getInputStream());
      byte[] buf = new byte[52100];
      int total = 0;
      while (true)
      {
        if (istream.available() > 0){
          int n = istream.read(buf, total, buf.length - total);
          total += n;
        }
        else{ // Data block is transmitted completely.
          txtComp.setText(new String(buf, 0, total, "UTF-8"));
          total = 0;
          istream = new GZIPInputStream(soc.getInputStream());
        }
      }
    }
    catch (Exception e){
      e.printStackTrace();
    }
  }
  
  private JTextComponent txtComp;
  private int port;
}


執行:
java com.jsptw.example.MsgReceiver [port=5271]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//MsgSender.java
package com.jsptw.example;
 
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.zip.GZIPOutputStream;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
 
public class MsgSender extends JFrame implements ActionListener {
 
  public MsgSender(String host, int port) throws UnknownHostException, IOException
  {
    super("Message sender");
    
    socket = new Socket(host, port);
    initComponents();
    
  }
 
  public void actionPerformed(ActionEvent e)
  {
    if (e.getActionCommand().equals(COMMAND_SEND)){
      try {
        GZIPOutputStream ostream = new GZIPOutputStream(
          socket.getOutputStream()
        );
        String msg = txt.getText() + "\n";
        ostream.write(
          msg.getBytes("UTF-8")
        );
        ostream.finish();
      }
      catch (IOException e1) {
        e1.printStackTrace();
      }
    }
    else if(e.getActionCommand().equals(COMMAND_CLEAR)){
      txt.setText(null);
      send.doClick();
    }
  }
 
  public static void main(String[] args) throws IOException
  {
    if (args.length < 2){
      printUsage();
      return;
    }
    
    JFrame frm = new MsgSender(args[0], Integer.parseInt(args[1]));
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frm.pack();
    frm.show();
  }
  
  public static void printUsage()
  {
    System.out.println(
      "Usage:\n" +
      "java MsgSender destination_host port\n\n" +
      "destination_host - receiver host location.\n" +
      "port - the port used to setup connection.\n"
    );
  }
 
  public void dispose()
  {
    super.dispose();
    if (!socket.isClosed()){
      try {
        socket.close();
      }
      catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  
  private void initComponents()
  {
    Container con = getContentPane();
    
    send = new JButton(COMMAND_SEND);
    send.addActionListener(this);
    JButton clear = new JButton(COMMAND_CLEAR);
    clear.addActionListener(this);
 
    JPanel tool = new JPanel(new GridLayout(1, 0, 5, 5));
    tool.add(send); tool.add(clear);
    con.add(tool, BorderLayout.SOUTH);
    
    txt = new JTextArea(15, 50);
    con.add(new JScrollPane(txt), BorderLayout.CENTER);
  }
  
  private JTextArea txt;
  private Socket socket;
  private static String COMMAND_SEND = "送出資料";
  private static String COMMAND_CLEAR = "清除內容";
  private JButton send;
}


執行:
java com.jsptw.example.MsgSender destination_host port


這樣的方法如果在傳送端是不斷的傳送一批一批的資料的話,是否行的通呢?
也就是說,利用while的方法不斷的傳送一批一批壓縮完的資料?


browser edited on 2003-08-22 18:12
reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:timothy]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-08-22 18:10 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
timothy wrote:
這樣的方法如果在傳送端是不斷的傳送一批一批的資料的話,是否行的通呢?
也就是說,利用while的方法不斷的傳送一批一批壓縮完的資料?


你覺得對接收端來說有差別嗎?

如果不考量傳送過程中發生失真的其他因素,我想是行得通的。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:GZIPOutputStream...? 程式很醜不要笑我...^^ [Re:timothy]
kotoway





發文: 30
積分: 2
於 2003-08-22 22:14 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
現在我發生一件事了,
我先把檔案壓縮後再送出去
server端也是一直收到 -1了...@@


kotoway edited on 2003-08-22 23:12
reply to postreply to post
作者 Re:GZIPOutputStream...? 程式很醜不要笑我...^^ [Re:kotoway]
timothy





發文: 24
積分: 0
於 2003-08-22 23:54 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
kotoway wrote:
現在我發生一件事了,
我先把檔案壓縮後再送出去
server端也是一直收到 -1了...@@


你這個問題比較好解決,如果你是接收完檔案之後沒有要再做任何傳輸的時候,那麼你判斷到這個-1冖後你便直接停止你的while就好了。萬一你還有要續續傳送資料的話,那麼可以利用上面的方式。


reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:Duncan]
timothy





發文: 24
積分: 0
於 2003-08-23 00:02 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
你覺得對接收端來說有差別嗎?

如果不考量傳送過程中發生失真的其他因素,我想是行得通的。


嗯!我認為對接收端來說是會有差別的。
因為以資料量小並不是連續傳送來說,在接收端很容易可以判斷到-1,在你所使用的方式中便可以重新建利一個GZIPOutputStream,然後繼續等待傳送端下一批的壓縮資料進來。如果說傳送端的資料不停的在傳送一定大小的資料(已壓縮過後的資料,大小若都在16K以上,或更小,不知道,又或者說資料量小也無所謂,只要是連續性的傳送),照理說,接收端可能就會產生問題了。要不要試試看把你那支程式小改一下,利用while不斷的傳送資料試試。


timothy edited on 2003-08-23 02:24
reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:timothy]
kotoway





發文: 30
積分: 2
於 2003-08-23 03:36 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
因為我是傳壓縮後的圖,我傳了13kb,35kb,75kb(這些都是壓縮後的)
在我傳圖前,我先送圖的大小,然後再送圖片,
server端我依照Duncan 兄的做法,讓total=大小後,就break;
這樣就不會跑無限迴圈了!!


reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:timothy]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-08-23 16:05 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
timothy wrote:
嗯!我認為對接收端來說是會有差別的。
因為以資料量小並不是連續傳送來說,在接收端很容易可以判斷到-1,在你所使用的方式中便可以重新建利一個GZIPOutputStream,然後繼續等待傳送端下一批的壓縮資料進來。如果說傳送端的資料不停的在傳送一定大小的資料(已壓縮過後的資料,大小若都在16K以上,或更小,不知道,又或者說資料量小也無所謂,只要是連續性的傳送),照理說,接收端可能就會產生問題了。要不要試試看把你那支程式小改一下,利用while不斷的傳送資料試試。


首先要探討這個問題,我們要先同意一項前提,那就是發送端每次傳送的資料不能大於 52100 bytes(這是我的筆誤 Tongue 大家都看得出來本來是 51200)。

依照你提出的情況,的確是會出問題,但是有一些因素要一併考量進來。source code 不長,架構也很簡單單純,其實各位可以自己改一改試試看。

首先所謂的發送端用 loop 一直傳送 szie < 52100 bytes 的 data,是指每一批資料已預先準備好了,然後以 loop 分批傳送,亦或是在 loop 的每一個 iteration 裡才準備資料並傳送出去?這裡的重點是資料的準備其實是 time-consuming 的動作,也就是其實每一批資料的傳送並不是想像中在時間上差距極微小的連續傳送,但反過來想:如果資料都已事先備妥,為何需要分批傳送呢?除了接收端 buffer 的大小所帶來的限制外。

另外我考量的是傳送/接收端的執行效率,這和硬體的配備有關以及兩端負責執行傳送/接收動作的執行緒之 priority 有關。為了簡化實驗的變數,我在我自己的電腦上(windows 2000 pro + AMD K7 550 MHz) 作 local 端的測試,資料預先備妥,MsgSender/MsgReceiver 在同一個 VM 下運作,我發現當 MsgReceiver 的 priority 接近 MsgSender 的 priority 時(even the former is less than the latter one),發送端連續傳送 50 筆小於 1 kbytes 的資料可以正確的運作。但如果每一批的資料 size 在 16k 上下,我讓接收端 priority=10,發送端 priority=4 才能成功連續發送/接收 50 筆 data,不過因為接收端我修改過接收端程式,使得在每一個 iteration 都會印出 verbose 資料到 standard output,這使得其執行花了更多的時間(印 data 到 standard outout 是很花時間的),而且這也跟接收端視窗大小有關(視窗越小 JTextArea 重繪的部分越小,越不耗時間)。

有興趣的人可以隨意更改 source 作試驗。最後我要提醒一點,當初放這個 source 只是點出有這樣的方式來傳送一批一批的資料,如果你的應用場合允許,你可以採用這方式,並沒有說這是個通吃各種需求的 solution。

簡單的設計自然只能帶能簡單的應用效益,我不會期望這個完全沒有 application specific 通訊協定的方式能應用在多數更複雜的場合,應該針對特殊的應用發展一套特殊的通訊方式(protocol)。


Duncan edited on 2003-08-23 16:42
reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:GZIPOutputStream...? [Re:Duncan]
timothy





發文: 24
積分: 0
於 2003-08-23 18:29 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
首先要探討這個問題,我們要先同意一項前提,那就是發送端每次傳送的資料不能大於 52100 bytes(這是我的筆誤 Tongue 大家都看得出來本來是 51200)。

依照你提出的情況,的確是會出問題,但是有一些因素要一併考量進來。source code 不長,架構也很簡單單純,其實各位可以自己改一改試試看。

首先所謂的發送端用 loop 一直傳送 szie < 52100 bytes 的 data,是指每一批資料已預先準備好了,然後以 loop 分批傳送,亦或是在 loop 的每一個 iteration 裡才準備資料並傳送出去?這裡的重點是資料的準備其實是 time-consuming 的動作,也就是其實每一批資料的傳送並不是想像中在時間上差距極微小的連續傳送,但反過來想:如果資料都已事先備妥,為何需要分批傳送呢?除了接收端 buffer 的大小所帶來的限制外。

另外我考量的是傳送/接收端的執行效率,這和硬體的配備有關以及兩端負責執行傳送/接收動作的執行緒之 priority 有關。為了簡化實驗的變數,我在我自己的電腦上(windows 2000 pro + AMD K7 550 MHz) 作 local 端的測試,資料預先備妥,MsgSender/MsgReceiver 在同一個 VM 下運作,我發現當 MsgReceiver 的 priority 接近 MsgSender 的 priority 時(even the former is less than the latter one),發送端連續傳送 50 筆小於 1 kbytes 的資料可以正確的運作。但如果每一批的資料 size 在 16k 上下,我讓接收端 priority=10,發送端 priority=4 才能成功連續發送/接收 50 筆 data,不過因為接收端我修改過接收端程式,使得在每一個 iteration 都會印出 verbose 資料到 standard output,這使得其執行花了更多的時間(印 data 到 standard outout 是很花時間的),而且這也跟接收端視窗大小有關(視窗越小 JTextArea 重繪的部分越小,越不耗時間)。

有興趣的人可以隨意更改 source 作試驗。最後我要提醒一點,當初放這個 source 只是點出有這樣的方式來傳送一批一批的資料,如果你的應用場合允許,你可以採用這方式,並沒有說這是個通吃各種需求的 solution。

簡單的設計自然只能帶能簡單的應用效益,我不會期望這個完全沒有 application specific 通訊協定的方式能應用在多數更複雜的場合,應該針對特殊的應用發展一套特殊的通訊方式(protocol)。


嗯!我正是有所需求,所以才想提出來,看看是否有解決之道。我現在也正在試驗,因為以我的需要來說,傳送端是會不停的傳送資料出去,而每一筆資料大小都不等,但壓縮後大約都保持在16K以下,正為了要正確接數每一筆資料煩惱中...


reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:timothy]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-08-23 20:38 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
timothy wrote:
嗯!我正是有所需求,所以才想提出來,看看是否有解決之道。我現在也正在試驗,因為以我的需要來說,傳送端是會不停的傳送資料出去,而每一筆資料大小都不等,但壓縮後大約都保持在16K以下,正為了要正確接數每一筆資料煩惱中...


之前你好像有 post 你的 source,後來砍掉了?

沒看清楚你的資料是如何準備(收集)的,若如同我先前提到資料的準備是耗時的,其實資料並不是如你想像般的連續。應該不需要太複雜的機制就可以 work。

不介意的話,你可以附檔方式把 source code 貼出來,讓感興趣的人來看看。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:GZIPOutputStream...? [Re:Duncan]
koji

秒速5センチメートル

站長

發文: 8420
積分: 19
於 2003-08-23 23:08 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
抱歉>.<請問鄧肯先生
那個51200byte是在哪邊有資料阿??

koji


reply to postreply to post
作者 Re:GZIPOutputStream...? [Re:koji]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-08-24 00:39 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
koji wrote:
抱歉>.<請問鄧肯先生
那個51200byte是在哪邊有資料阿??

koji


一頭霧水Question

我 post 的 source code 裡使用了 52100 bytes 的 buffer,我本來是是想定 50 kb...............這沒有什麼重要的,就是 buffer 而已,並沒有什麼理由(研究)指出這個量有什麼好處。


reply to postreply to post

給我
辣味豆腐 其餘免談
go to first page go to previous page  1   2  go to next page go to last page
» JWorld@TW »  Java SE 討論區

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8