BeginWrite/BeginRead libérera votre thread en cours et faire des choses dans l'arrière-plan. Vous pouvez mettre en file d'attente plusieurs écritures avec BeginWrite (et avoir une idée du travail parallèle). Je ne le recommanderais pas, car le tampon de socket interne peut être plein lors de l'envoi de fichiers.
Vous pouvez toujours passer à un socket et utiliser la méthode SendFile.
Si vous avez plusieurs TcpClient ou Sockets, vous pouvez utiliser les méthodes BeginWrite/BeginRead pour les gérer sans avoir à créer un nouveau thread pour chacun d'entre eux. Ci-dessous un petit exemple qui se connecte au serveur, envoie un fichier et se déconnecte. Il peut gérer n'importe quelle quantité de clients tcp ouverts. Et comme vous le voyez, il n'utilise pas de fils (il est fait en arrière-plan par framework .Net)
/// <summary>
/// Thread safe queue of client ids
/// </summary>
internal class FileSender
{
/// <summary>
/// A write operation have completed
/// </summary>
/// <param name="ar"></param>
private void OnWriteCompleted(IAsyncResult ar)
{
// We passed the context to this method, cast it back
var context = (ClientContext) ar.AsyncState;
// end the write
context.TcpClient.GetStream().EndWrite(ar);
// we've completed.
if (context.BytesSent >= context.FileStream.Length)
{
// notify any listener
Completed(this, new CompletedEventArgs(context.RemoteEndPoint, context.FileStream.Name));
context.TcpClient.Close();
return;
}
// Send more data from the file to the server.
int bytesRead = context.FileStream.Read(context.Buffer, 0, context.Buffer.Length);
context.BytesSent += bytesRead;
context.TcpClient.GetStream().BeginWrite(context.Buffer, 0, bytesRead, OnWriteCompleted, context);
}
/// <summary>
/// Send a file
/// </summary>
/// <param name="endPoint"></param>
/// <param name="fullPath"></param>
public void SendFile(IPEndPoint endPoint, string fullPath)
{
// Open a stream to the file
var stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read);
// Create a client and connect to remote end
var client = new TcpClient();
client.Connect(endPoint);
// Context is used to keep track of this client
var context = new ClientContext
{
Buffer = new byte[65535],
FileStream = stream,
TcpClient = client,
RemoteEndPoint = endPoint
};
// read from file stream
int bytesRead = stream.Read(context.Buffer, 0, context.Buffer.Length);
// and send the data to the server
context.BytesSent += bytesRead;
client.GetStream().BeginWrite(context.Buffer, 0, bytesRead, OnWriteCompleted, context);
}
/// <summary>
/// File transfer have been completed
/// </summary>
public event EventHandler<CompletedEventArgs> Completed = delegate { };
#region Nested type: ClientContext
/// <summary>
/// Used to keep track of all open connections
/// </summary>
private class ClientContext
{
/// <summary>
/// Gets or sets buffer used to send file
/// </summary>
public byte[] Buffer { get; set; }
/// <summary>
/// Gets or sets number of bytes sent.
/// </summary>
public int BytesSent { get; set; }
/// <summary>
/// Gets or sets file to send
/// </summary>
public FileStream FileStream { get; set; }
public IPEndPoint RemoteEndPoint { get; set; }
/// <summary>
/// Gets or sets client sending the file
/// </summary>
public TcpClient TcpClient { get; set; }
}
#endregion
}
internal class CompletedEventArgs : EventArgs
{
public CompletedEventArgs(IPEndPoint endPoint, string fullPath)
{
EndPoint = endPoint;
FullPath = fullPath;
}
public IPEndPoint EndPoint { get; private set; }
public string FullPath { get; private set; }
}
tcpclient.connect (remotehost, port) si j'envoie le port autre que l'on utilise pour la fabrication connexion alors il lance une erreur (refus de connexion) en faisant avec le même port, le rend même objet. – marshalprince
Mais si vous utilisez une connexion, comment le serveur saura-t-il quelles données appartiennent ensemble? –
ce que je fais est, pour faire une connexion j'utilise un TCPClient et pour lequel j'envoie \ recevoir le fichier que je crée un autre TCPClient mais maintenant je dois verrouiller le premier i.e utilisé pour la connexion. Mais entre les deux si j'ai besoin d'envoyer les données avec un autre thread (je fais un nouveau TCPClient pour les données) mais pour la connexion TCPClient est déjà verrouillé. Alors, comment puis-je envoyer un autre fichier – marshalprince