Je souhaite utiliser TcpClient et TcpListener pour envoyer un fichier mp3 sur un réseau. J'ai implémenté une solution à l'aide de sockets, mais il y a eu quelques problèmes, donc j'étudie une nouvelle/meilleure façon d'envoyer un fichier.Tableau d'octets bousillés après l'utilisation de TcpClient et TcpListener
créer un tableau d'octets qui ressemble à ceci: length_of_filename | nom | fichier
Cela devrait ensuite être transmis en utilisant les classes mentionnées ci-dessus, mais sur le côté serveur du tableau d'octets que je lis est complètement foiré et Je ne suis pas sûr pourquoi.
La méthode que j'utilise pour envoyer:
public static void Send(String filePath)
{
try
{
IPEndPoint endPoint = new IPEndPoint(Settings.IpAddress, Settings.Port + 1);
Byte[] fileData = File.ReadAllBytes(filePath);
FileInfo fi = new FileInfo(filePath);
List<byte> dataToSend = new List<byte>();
dataToSend.AddRange(BitConverter.GetBytes(Encoding.Unicode.GetByteCount(fi.Name))); // length of filename
dataToSend.AddRange(Encoding.Unicode.GetBytes(fi.Name)); // filename
dataToSend.AddRange(fileData); // file binary data
using (TcpClient client = new TcpClient())
{
client.Connect(Settings.IpAddress, Settings.Port + 1);
// Get a client stream for reading and writing.
using (NetworkStream stream = client.GetStream())
{
// server is ready
stream.Write(dataToSend.ToArray(), 0, dataToSend.ToArray().Length);
}
}
}
catch (ArgumentNullException e)
{
Debug.WriteLine(e);
}
catch (SocketException e)
{
Debug.WriteLine(e);
}
}
}
Ensuite, du côté du serveur, il se présente comme suit:
private void Listen()
{
TcpListener server = null;
try
{
// Setup the TcpListener
Int32 port = Settings.Port + 1;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[1024];
List<byte> data;
// Enter the listening loop.
while (true)
{
Debug.WriteLine("Waiting for a connection... ");
string filePath = string.Empty;
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
using (TcpClient client = server.AcceptTcpClient())
{
Debug.WriteLine("Connected to client!");
data = new List<byte>();
// Get a stream object for reading and writing
using (NetworkStream stream = client.GetStream())
{
// Loop to receive all the data sent by the client.
while ((stream.Read(bytes, 0, bytes.Length)) != 0)
{
data.AddRange(bytes);
}
}
}
int fileNameLength = BitConverter.ToInt32(data.ToArray(), 0);
filePath = Encoding.Unicode.GetString(data.ToArray(), 4, fileNameLength);
var binary = data.GetRange(4 + fileNameLength, data.Count - 4 - fileNameLength);
Debug.WriteLine("File successfully downloaded!");
// write it to disk
using (BinaryWriter writer = new BinaryWriter(File.Open(filePath, FileMode.Append)))
{
writer.Write(binary.ToArray(), 0, binary.Count);
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
}
Quelqu'un peut-il voir quelque chose que je manque/faire le mal?
Le code suivant pourrait-il donner le même résultat? while ((stream.Read (octets, 0, octets.length))! = 0) { data.AddRange (octets); bytes = nouvel octet [bytes.Length]; } Pour que "octets" soit réinitialisé dans chaque boucle, aucune donnée précédente n'est conservée. –
@J Pollack Ce code souffrira d'un problème similaire au code d'origine. La seule différence est que lorsque 'bytes' n'a pas été rempli par' stream.Read', l'appel à 'data.AddRange' ajoutera des zéros supplémentaires au lieu des données d'un appel' stream.Read' plus ancien. –
Ross vous avez absolument raison. J'ai espéré que la partie vide du dernier tampon partiellement rempli n'est pas ajoutée par data.AddRange (bytes). C'était évidemment une pensée trop optimiste.Merci d'expliquer. Si vous traitez avec des chaînes, il peut être traité avec easy: data + = Encoding.UTF8.GetString (octets, 0, longueur); –