代码之家  ›  专栏  ›  技术社区  ›  Jorge Córdoba

如何使用TcpListener/Client通过tcp发送文件?SocketException问题

  •  4
  • Jorge Córdoba  · 技术社区  · 17 年前

    我正在开发一个简单的应用程序,使用TCPListener和TCPClient类通过TCP发送文件。这是发送文件的代码。

    Stop是一个易失性布尔值,它有助于随时停止进程,并且写入缓冲区大小可能会在运行时更改(另一个易失性)

    while (remaining > 0 && !stop)
    {
      DateTime current = DateTime.Now;
      int bufferSize = WRITTE_BUFFER_SIZE;
      buffer = new byte[bufferSize];
      int readed = fileStream.Read(buffer, 0, bufferSize);
      stream.Write(buffer, 0, readed);
      stream.Flush();
      remaining -= readed;
      // Wait in order to guarantee send speed
      TimeSpan difference = DateTime.Now.Subtract(current);
      double seconds = (bufferSize / Speed);
      int wait = (int)Math.Floor(seconds * 1000);
      wait -= difference.Milliseconds;
      if (wait > 10)
        Thread.Sleep(wait);
    }                
    stream.Close();
    

    这是处理接收器端的代码:

    do
    {
      readed = stream.Read(buffer, 0, READ_BUFFER_SIZE);
      // write to .part file and flush to disk
      outputStream.Write(buffer, 0, readed);
      outputStream.Flush();
      offset += readed;
    } while (!stop && readed > 0);
    

    编辑: 我收到此错误“无法从传输连接读取数据”。这是一个IOException,其内部异常是SocketException。

    我已经在sender函数中添加了这个,但是我仍然得到了相同的错误,代码从未到达stream.close(),当然tcpclient也从未真正关闭过。。。所以我现在完全迷路了。

    buffer = new byte[1];
    client.Client.Receive(buffer);
    stream.Close();
    
    1 回复  |  直到 17 年前
        1
  •  1
  •   grieve    17 年前

    • 完成发送数据。
    • 调用shutdown(),将how参数设置为1。
    • 调用closesocket()。

    http://tangentsoft.net/wskfaq/newbie.html#howclose

    C#sharp可能已经在其库中纠正了这一点,但我对此表示怀疑,因为它们是建立在winsock API之上的。

    编辑:

    另外,让缓冲区大小不稳定不是线程安全的,也不会给您带来任何好处。使用stop作为volatile是安全的,但不要期望它是即时的。换句话说,循环在获得更新的stop值之前可以再运行几次。在多处理器机器上尤其如此。

    编辑(02):

    // write all the bytes
    // Then do the following
    
    client.client.Shutdown(Shutdown.Send) // This assumes you have access to this protected member
    while (stream.read(buffer, 0, READ_BUFFER_SIZE) != 0);
    client.close()