c#tcp编程一种将二进制文件从客户端传输到服务器的简单方法

时间:2017-07-23 06:56:12

标签: c# python sockets tcp

我正在做关于TCP服务器和客户端的项目,所以这个项目我要传输二进制文件,如:

  • .EXE
  • .JPG
  • .DOCX
  • .txt的
  • 的.dll
  • 等..

我已经在我的代码中尝试了很多不同的方法来传输文件但仍然失败。

使用此代码时出现问题,传输的文件大小超过9kb:

byte[] ba = File.ReadAllBytes(filename);
  1. 一切都很好,因为我读了文件中的所有字节
  2. 之后我使用:

    将其发送到服务器
    stm.Write(ba, 0, ba.Length);
    
  3. 客户端已成功将数据发送到服务器

  4. 在服务器上,代码就是这样从客户端接收文件数据:

    recv = "";
    byte[] bb = new byte[8000000];
    int k = control.Receive(bb);
    for (int i = 0; i < k; i++)
        recv += Convert.ToChar(bb[i]);
    rec = Convert.ToString(recv);
    byte[] array = Encoding.ASCII.GetBytes(rec);
    File.WriteAllBytes(filename, array);
    MessageBox.Show("download success!");
    
  5. 因此服务器成功从客户端接收数据并对服务器进行编码 到字节数组并使用以下数据将数据保存到文件中:

    File.WriteAllBytes(filename, array);
    
  6. 问题是

    1. 我发送的文件大小超过9 kb
    2. 当服务器在文件中写入数据时,它只会破坏文件 和大小文件与客户端
    3. 的实际文件大小完全相同

      那我的问题是什么?以及如何解决?

      如果python很容易使用超时来获取大数据,就像这段代码一样:

      import socket
      import os
      import sys
      from thread import *
      import time
      import random
      def recv_timeout(socket,timesz):
          socket.setblocking(0)
              total_data=[]
              data=""
              begin=time.time()
              while 1:
                  if total_data and time.time()-begin >timesz:
                      break
                  elif time.time()-begin > timesz*2:
                      break
                  try:
                      data = socket.recv(8192)
                      if data:
                          total_data.append(data)
                          begin=time.time()
                      else:
                          time.sleep(0.1)
                  except:
                      pass
          return ''.join(total_data) 
      

      我使用此代码接收大数据并成功接收jpg文件..是否可以在C#上使用python中的此方法?

2 个答案:

答案 0 :(得分:0)

对于你的python代码,没有必要自己阅读解除阻塞和阻塞。所有等待和超时机制都内置在您的套接字中:

def recv_all(socket):
    total_data = []
    while True:
        data = socket.recv(8192)
        if not data:
            break
        total_data.append(data)
    return ''.join(total_data)

您必须在C#代码中执行相同操作:接收数据,直到发送方的套接字关闭。

recv = "";
int k;
do {
    byte[] bb = new byte[8000];
    k = control.Receive(bb);
    for (int i = 0; i < k; i++)
        recv += Convert.ToChar(bb[i]);
} while(k);

答案 1 :(得分:0)

您不需要将所有字节编码为字符串。试试这段代码:

var chunkSize = 8000000;
byte[] bb = new byte[chunkSize];
using (var file = File.OpenWrite(filename))
{
    while (true)
    {
        var bytesReceived = control.Receive(bb);
        file.Write(bb, 0, bytesReceived);
        if (bytesReceived < chunkSize)
            break;
    }
}
MessageBox.Show("download success!");