L'envoi d'un fichier à l'aide de TCPClient et NetworkStream en C#
J'ai essayé d'envoyer un fichier à partir d'un client à un serveur d'applications à l'aide de la classe TCPClient en C#. Avant d'envoyer les données réelles, j'envoie quelques informations supplémentaires comme la taille du fichier exacte et le nom de fichier, de sorte que le serveur d'application sait combien il y a à lire. Le plus drôle, c'est que tout allait bien quand je l'ai testé sur 127.0.0.1 - dès que j'ai remplacé l'adresse IP avec le réel, le serveur ne pouvait lire qu'à environ 1,5 kilo-octets de données qui ont été envoyées. Il obtient toujours le nom de fichier et la taille du fichier, mais theres aucun moyen de récupérer les données réelles.
Des fins de test, j'ai remplacé l'image que j'allais envoyer une chaîne simple et la transmission est allé très bien, donc je suppose qu'il y a un problème avec l'envoi et la réception de données de morceaux, mais je ne reçois pas toutes les exceptions sur le côté client.
Quelqu'un a une idée? Cheers!
Edit:
Merci beaucoup, c'est ce que j'ai codewise. Pour le client:
IPAddress ipAddress = IPAddress.Parse("xx.xx.xx.xx");
int port = 3003;
int bufferSize = 1024;
TcpClient client = new TcpClient();
NetworkStream netStream;
//Connect to server
try
{
client.Connect(new IPEndPoint(ipAddress, port));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
netStream = client.GetStream();
//Read bytes from image
byte[] data = File.ReadAllBytes("C:\\Users\\Dan\\Desktop\\asdf.jpg");
//Build the package
byte[] dataLength = BitConverter.GetBytes(data.Length);
byte[] package = new byte[4 + data.Length];
dataLength.CopyTo(package, 0);
data.CopyTo(package, 4);
//Send to server
int bytesSent = 0;
int bytesLeft = package.Length;
while (bytesLeft > 0)
{
int nextPacketSize = (bytesLeft > bufferSize) ? bufferSize : bytesLeft;
netStream.Write(package, bytesSent, nextPacketSize);
bytesSent += nextPacketSize;
bytesLeft -= nextPacketSize;
}
//Clean up
netStream.Close();
client.Close();
Et le serveur:
TcpListener listen = new TcpListener(3003);
TcpClient client;
int bufferSize = 1024;
NetworkStream netStream;
int bytesRead = 0;
int allBytesRead = 0;
//Start listening
listen.Start();
//Accept client
client = listen.AcceptTcpClient();
netStream = client.GetStream();
//Read length of incoming data
byte[] length = new byte[4];
bytesRead = netStream.Read(length, 0, 4);
int dataLength = BitConverter.ToInt32(length,0);
//Read the data
int bytesLeft = dataLength;
byte[] data = new byte[dataLength];
while (bytesLeft > 0)
{
int nextPacketSize = (bytesLeft > bufferSize) ? bufferSize : bytesLeft;
bytesRead = netStream.Read(data, allBytesRead, nextPacketSize);
allBytesRead += bytesRead;
bytesLeft -= bytesRead;
}
//Save image to desktop
File.WriteAllBytes("C:\\Users\\Dan\\Desktop\\tcpimage.jpg", data);
//Clean up
netStream.Close();
client.Close();
J'ai peur que nous avons besoin de voir un peu de code. Tester en local et à distance peut donner des résultats très différents (pour l'un, les tests localement est un peu comme direct si vous avez l'habitude de rencontrer la commune de gotcha que rapidement)
Avez-vous réellement lu dans une boucle, ou avez-vous simplement appeler
Read
une fois? Vous pouvez également utiliser BinaryReader.ReadToEnd
Merci beaucoup, j'ai ajouté le code dans le post original. Cheers
Et ce qui se passe à NetworkStream.Lire lorsque vous avez reçu 1500 octets? Est-il bloquer? Est-il de retour à zéro?
OriginalL'auteur gbr | 2012-04-01
Vous devez vous connecter pour publier un commentaire.
Environ 1,5 KiB sons de 1500 octets, "la plus grande autorisée par Ethernet au niveau de la couche réseau". C'est le l'unité de transmission maximale (mtu) forcer votre pile de réseau de diviser un fichier en plusieurs petits paquets.
Vous devez appeler la NetworkStream.Lire dans une boucle pour lire chaque paquet est arrivé. Il y a un code d'exemple de ce à MSDN.
Combinez cela avec le comportement par défaut des .NET; consolidation des paquets plus petits pour réduire la quantité de paquets envoyés, et vous verrez aussi ce problème lors de l'envoi de petits paquets. Cela peut être contrôlé avec ServicePointManager.UseNagleAlgorithm ou en utilisant une petite étendue options de prise.
OriginalL'auteur sisve
J'ai utilisé une partie de votre code pour le test d'un projet de mise en réseau, je suis en train de travailler sur. J'ai modifié quelques petites choses pour s'adapter aux exigences de mon projet, mais une altération j'avais besoin de faire pour le code d'origine est d'ajouter un "-4" à la ligne qui a été réglage de la bytesLeft variable. Après que le code a fonctionné. Mon fichier de test est 52KB & a été transmis avec succès.
OriginalL'auteur Mr Smith
Ok, je ne sais pas ce que je fais ici, maisdans le cas de quelqu'un utilise ce que referrence.Je me suis débarrassé de copie inutile et fait un très amélioration importante. Votre chemin de calc
nextPacketSize
n'est pas complète, car il pourrait y avoir moins de données, de 1024 disponible, et vous pourrez obtenir plus de zéros entre ces morceaux (j'ai eu beaucoup de maux de tête avec ça, maintenant si heureux de la figure)J'ai fait en fonction, nécessaire pour plusieurs fichiers, donc voici le code:
client
celui-ci est presque la même
serveur
OriginalL'auteur Evilkeeper