#c# #asp.net
#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 байт. Пожалуйста, помогите кому-нибудь. Не знаете y? Во время чтения последнего набора данных он выходит из цикла 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();
}
}
}
Комментарии:
1. Похоже, вы игнорируете данные, которые уже были прочитаны при запуске вашего обратного вызова, и затем вы синхронно считываете остальные данные, что в значительной степени сводит на нет тот факт, что первое чтение было асинхронным в первую очередь. Вам действительно нужен асинхронный ввод-вывод на данный момент? Я предлагаю вам сначала заставить его работать с синхронным вводом-выводом…
2. @JonSkeet Мне нужно читать данные только асинхронно. Пожалуйста, скажите, что нужно сделать, чтобы прочитать все данные? Спасибо за быстрый ответ!!
3. @user1805948: Почему бы вам не использовать существующие библиотеки, которые позаботятся обо всех операциях ввода-вывода для вас?
4. @jgauffin Я не получил u?? Какие существующие библиотеки? Можете ли вы уточнить, пожалуйста.
5. Я его создал. Хотите посмотреть, как вы можете отправить файл с ним?
Ответ №1:
Вот пример, в котором используется моя библиотека 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);
}
}
Библиотека может отправлять / получать потоки любого типа любого размера (при условии, что размер известен). Клиент автоматически создаст MemoryStream
или FileStream
в зависимости от размера потока.
Комментарии:
1. Это совершенно сложный вопрос, на который я не могу положиться.
2. создание собственного сокета-клиента / сервера намного сложнее 😉