通过TCPClient发送和接收大量数据时,不会读取所有数据

本文关键字:数据 读取 TCPClient 通过 | 更新日期: 2023-09-27 18:08:50

在此代码中接收字节(服务器)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Drawing;
namespace ByteLengthReading
{
    class Program
    {
        static void Main(string[] args)
        {
            StartServer();            
        }
        private static TcpListener _listener;
        public static void StartServer()
        { 
            IPAddress localIPAddress = IPAddress.Parse("119.43.29.182");
            IPEndPoint ipLocal = new IPEndPoint(localIPAddress, 8001);
            _listener = new TcpListener(ipLocal);
            _listener.Start();
            WaitForClientConnect();
        }
        private static void WaitForClientConnect()
        {
            object obj = new object();
            _listener.BeginAcceptTcpClient(new System.AsyncCallback(OnClientConnect), obj);
            Console.In.ReadLine();
        }
        private static void OnClientConnect(IAsyncResult asyn)
        {            
            try
            {
               TcpClient clientSocket = default(TcpClient);
                clientSocket = _listener.EndAcceptTcpClient(asyn);
                HandleClientRequest clientReq = new HandleClientRequest(clientSocket);
                clientReq.StartClient();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            WaitForClientConnect();
        }
        public class HandleClientRequest
        {
            TcpClient _clientSocket;
            NetworkStream _networkStream = null;
            public HandleClientRequest(TcpClient clientConnected)
            {
                this._clientSocket = clientConnected;
            }
            public void StartClient()
            {
                _networkStream = _clientSocket.GetStream();
                WaitForRequest();
            }
            public void WaitForRequest()
            {
                byte[] buffer = new byte[_clientSocket.ReceiveBufferSize];
                _networkStream.BeginRead(buffer, 0, buffer.Length, ReadCallback, buffer);
            }
            private void ReadCallback(IAsyncResult result)
            {                
                NetworkStream networkStream = _clientSocket.GetStream();
                byte[] buffer = new byte[16384];
                int read = -1;
                int totRead = 0;

                using (FileStream fileStream = new FileStream(@"C:'Foo" + Guid.NewGuid().ToString("N") + ".txt", FileMode.Create))
                {
                    while ((read = networkStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        totRead += read;
                        fileStream.Write(buffer, 0, read);
                        Console.WriteLine("Total Read" + totRead);
                        //fileStream.Write(buffer, 0, totRead);
                        //fileStream.Close();
                    }
                    fileStream.Close();
                }
            }
        }

}

发送字节(客户端),发送字节长度为4047810。但是上面的服务器代码只接收了4039618字节。请帮帮别人吧。不知道?在读取最后一组数据时,它从while循环中出来。请测试这段代码并告诉我问题出在哪里。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Drawing;
using System.Threading;
namespace ByteLengthSending
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            client.Connect(IPAddress.Parse("119.43.29.182"), 8001);
            //IPAddress ipAd = IPAddress.Parse("119.43.29.182");
            //TcpClient client = new TcpClient(ipAd.ToString(), 8001);
            //NetworkStream stream = client.GetStream();
            int totread = 0;
            byte[] longBuffer = new byte[3824726];
            byte[] buffer = new byte[4096];
            using (var fileStream = File.OpenRead("C:/Foo.txt"))            
            {
                while (true)
                {
                    int read = fileStream.Read(buffer, 0, buffer.Length);
                    totread += read;
                    if (read <= 0)
                    {
                        break;
                    }
                    for (int sendBytes = 0; sendBytes < read; sendBytes += client.Send(buffer, sendBytes, read - sendBytes, SocketFlags.None))
                    {
                    }
                }                
            }
            client.Close();
            Console.WriteLine("Total Read" + totread);
            Console.In.ReadLine();
        }
    }
}

通过TCPClient发送和接收大量数据时,不会读取所有数据

下面是一个使用我的库Griffin的示例。框架传输文件(Apache许可证)。

你所需要做的就是安装nuget包griffin.framework,然后创建一个控制台应用程序,用下面的代码替换Program类:

class Program
{
    static void Main(string[] args)
    {
        var server = new ChannelTcpListener();
        server.MessageReceived = OnServerReceivedMessage;
        server.Start(IPAddress.Any, 0);
        var client = new ChannelTcpClient<object>(new MicroMessageEncoder(new DataContractMessageSerializer()),
            new MicroMessageDecoder(new DataContractMessageSerializer()));
        client.ConnectAsync(IPAddress.Loopback, server.LocalPort).Wait();
        client.SendAsync(new FileStream("TextSample.txt", FileMode.Open)).Wait();

        Console.ReadLine();
    }
    private static void OnServerReceivedMessage(ITcpChannel channel, object message)
    {
        var file = (Stream) message;
        var reader = new StreamReader(file);
        var fileContents = reader.ReadToEnd();
        Console.WriteLine(fileContents);
    }
}

标准库可以发送/接收任何大小的流(只要大小是已知的)。客户端将根据流的大小自动创建MemoryStreamFileStream