c# - 通过TCP客户端发送和接收大量数据并没有读取所有数据

标签 c# asp.net

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

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();
        }
    }
}

最佳答案

这是一个使用我的库的示例 Griffin.Framework传输文件(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

关于c# - 通过TCP客户端发送和接收大量数据并没有读取所有数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24256974/

相关文章:

c# - 数据集 - 无法读取 XML 1.1?

c# - 如何轻松地从编译中排除某些代码行?

c# - 为什么我必须为 Code First/Entity Framework 使用无参数构造函数

asp.net - 如何停止调用 500 错误页面创建的 500 .net 错误

c# - .net 代码隐藏页面中的 GetElementsByTagName 功能?

javascript - jQuery 获取表格行中的隐藏字段值

javascript - 单击下拉列表更改 css

c# - 从网站获取字符串

c# - 将扩展方法中的事件和函数分配为参数

javascript - 当我单击 ajax 选项卡控件时,它显示一个矩形框如何在 asp.net 中删除