通过TCP压缩和传输文件(使用Golang)

huangapple go评论109阅读模式
英文:

Compress and transfer file via TCP (Golang)

问题

我写了一个简单的示例代码,它可以工作,但是接收到的文件大小没有被压缩。

我的客户端(用于连接服务器和发送文件):

  1. // 连接服务器
  2. conn, err := net.Dial("tcp", serverAddr)
  3. CheckError(err)
  4. defer conn.Close()
  5. in, err := os.Open(srcFile)
  6. if err != nil {
  7. log.Fatal(err)
  8. }
  9. pr, pw := io.Pipe()
  10. gw, err := gzip.NewWriterLevel(pw, 7)
  11. CheckError(err)
  12. go func() {
  13. n, err := io.Copy(gw, in)
  14. gw.Close()
  15. pw.Close()
  16. log.Printf("copied %v %v", n, err)
  17. }()
  18. // 可能在下面会出错?
  19. _, err = io.Copy(conn, pr)

请帮忙,如何正确使用管道(pipe)和拷贝(copy)函数?

英文:

I write simple example code, it worked, but size of file that recived is not compressed

My client (for connect to server and send file):

  1. // connect to server
  2. conn, err := net.Dial("tcp", serverAddr)
  3. CheckError(err)
  4. defer conn.Close()
  5. in, err := os.Open(srcFile)
  6. if err != nil {
  7. log.Fatal(err)
  8. }
  9. pr, pw := io.Pipe()
  10. gw, err := gzip.NewWriterLevel(pw, 7)
  11. CheckError(err)
  12. go func() {
  13. n, err := io.Copy(gw, in)
  14. gw.Close()
  15. pw.Close()
  16. log.Printf("copied %v %v", n, err)
  17. }()
  18. //maybe error some next?
  19. _, err = io.Copy(conn, pr)

Please, help, how right to use pipe with copy

答案1

得分: 3

如我在评论中已经说过的那样,你的代码是有效的。我创建了一个小例子来测试或查看是否可以解决你的问题。所以我猜你可以关闭这个问题。

  1. package main
  2. import (
  3. "compress/gzip"
  4. "io"
  5. "log"
  6. "net"
  7. "os"
  8. )
  9. func main() {
  10. // 在一个随机端口上创建监听器。
  11. listener, err := net.Listen("tcp", "127.0.0.1:")
  12. if err != nil {
  13. log.Fatal(err)
  14. }
  15. log.Println("Server listening on: " + listener.Addr().String())
  16. done := make(chan struct{})
  17. go func() {
  18. defer func() { done <- struct{}{} }()
  19. for {
  20. conn, err := listener.Accept()
  21. if err != nil {
  22. log.Println(err)
  23. return
  24. }
  25. go func(c net.Conn) {
  26. defer func() {
  27. c.Close()
  28. done <- struct{}{}
  29. }()
  30. buf := make([]byte, 1024)
  31. for {
  32. n, err := c.Read(buf)
  33. if err != nil {
  34. if err != io.EOF {
  35. log.Println(err)
  36. }
  37. return
  38. }
  39. log.Printf("received: %q", buf[:n])
  40. log.Printf("bytes: %d", n)
  41. }
  42. }(conn)
  43. }
  44. }()
  45. conn, err := net.Dial("tcp", listener.Addr().String())
  46. if err != nil {
  47. log.Fatal(err)
  48. }
  49. log.Println("Connected to server.")
  50. file, err := os.Open("./file.txt")
  51. if err != nil {
  52. log.Fatal(err)
  53. }
  54. pr, pw := io.Pipe()
  55. w, err := gzip.NewWriterLevel(pw, 7)
  56. if err != nil {
  57. log.Fatal(err)
  58. }
  59. go func() {
  60. n, err := io.Copy(w, file)
  61. if err != nil {
  62. log.Fatal(err)
  63. }
  64. w.Close()
  65. pw.Close()
  66. log.Printf("copied to piped writer via the compressed writer: %d", n)
  67. }()
  68. n, err := io.Copy(conn, pr)
  69. if err != nil {
  70. log.Fatal(err)
  71. }
  72. log.Printf("copied to connection: %d", n)
  73. conn.Close()
  74. <-done
  75. listener.Close()
  76. <-done
  77. }

使用一个简单的文本文件作为输入,其中包含许多重复的字符,以便进行压缩,该程序的输出为:文件大小为153字节,发送/接收了46字节。

  1. 2022/04/04 11:23:58 Server listening on: 127.0.0.1:58250
  2. 2022/04/04 11:23:58 Connected to server.
  3. 2022/04/04 11:23:58 received: "\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff"
  4. 2022/04/04 11:23:58 bytes: 10
  5. 2022/04/04 11:23:58 copied to piped writer via the compressed writer: 153
  6. 2022/04/04 11:23:58 copied to connection: 46
  7. 2022/04/04 11:23:58 received: "*I-.I,NI,N\xc1\x01\x8aS\x8a\x13i\bx\xb9pX \r\b\x00\x00\xff\xff\xc7\xfe\xa6c\x99\x00\x00\x00"
  8. 2022/04/04 11:23:58 bytes: 36
  9. 2022/04/04 11:23:58 accept tcp 127.0.0.1:58250: use of closed network connection
英文:

As I already said in the comment, your code works. I created a little example to test or see if I can solve your problem. So I guess you can close this question.

  1. package main
  2. import (
  3. &quot;compress/gzip&quot;
  4. &quot;io&quot;
  5. &quot;log&quot;
  6. &quot;net&quot;
  7. &quot;os&quot;
  8. )
  9. func main() {
  10. // Create a listener on a random port.
  11. listener, err := net.Listen(&quot;tcp&quot;, &quot;127.0.0.1:&quot;)
  12. if err != nil {
  13. log.Fatal(err)
  14. }
  15. log.Println(&quot;Server listening on: &quot; + listener.Addr().String())
  16. done := make(chan struct{})
  17. go func() {
  18. defer func() { done &lt;- struct{}{} }()
  19. for {
  20. conn, err := listener.Accept()
  21. if err != nil {
  22. log.Println(err)
  23. return
  24. }
  25. go func(c net.Conn) {
  26. defer func() {
  27. c.Close()
  28. done &lt;- struct{}{}
  29. }()
  30. buf := make([]byte, 1024)
  31. for {
  32. n, err := c.Read(buf)
  33. if err != nil {
  34. if err != io.EOF {
  35. log.Println(err)
  36. }
  37. return
  38. }
  39. log.Printf(&quot;received: %q&quot;, buf[:n])
  40. log.Printf(&quot;bytes: %d&quot;, n)
  41. }
  42. }(conn)
  43. }
  44. }()
  45. conn, err := net.Dial(&quot;tcp&quot;, listener.Addr().String())
  46. if err != nil {
  47. log.Fatal(err)
  48. }
  49. log.Println(&quot;Connected to server.&quot;)
  50. file, err := os.Open(&quot;./file.txt&quot;)
  51. if err != nil {
  52. log.Fatal(err)
  53. }
  54. pr, pw := io.Pipe()
  55. w, err := gzip.NewWriterLevel(pw, 7)
  56. if err != nil {
  57. log.Fatal(err)
  58. }
  59. go func() {
  60. n, err := io.Copy(w, file)
  61. if err != nil {
  62. log.Fatal(err)
  63. }
  64. w.Close()
  65. pw.Close()
  66. log.Printf(&quot;copied to piped writer via the compressed writer: %d&quot;, n)
  67. }()
  68. n, err := io.Copy(conn, pr)
  69. if err != nil {
  70. log.Fatal(err)
  71. }
  72. log.Printf(&quot;copied to connection: %d&quot;, n)
  73. conn.Close()
  74. &lt;-done
  75. listener.Close()
  76. &lt;-done
  77. }

The output of that program with a simple text file with many repeated characters in it, to have something to compress: The file is 153 bytes and I send/received 46 bytes

  1. 2022/04/04 11:23:58 Server listening on: 127.0.0.1:58250
  2. 2022/04/04 11:23:58 Connected to server.
  3. 2022/04/04 11:23:58 received: &quot;\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff&quot;
  4. 2022/04/04 11:23:58 bytes: 10
  5. 2022/04/04 11:23:58 copied to piped writer via the compressed writer: 153
  6. 2022/04/04 11:23:58 copied to connection: 46
  7. 2022/04/04 11:23:58 received: &quot;*I-.I,NI,N\xc1\x01\x8aS\x8a\x13i\bx\xb9pX \r\b\x00\x00\xff\xff\xc7\xfe\xa6c\x99\x00\x00\x00&quot;
  8. 2022/04/04 11:23:58 bytes: 36
  9. 2022/04/04 11:23:58 accept tcp 127.0.0.1:58250: use of closed network connection

huangapple
  • 本文由 发表于 2022年4月2日 09:22:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/71714183.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定