2010-03-16 10 views
2

Existe-t-il un moyen de gérer les sessions avec des sockets en C#?Socket TCP .NET avec session

Exemple de mon problème:
J'ai un serveur avec une prise écoute sur le port 5672.

TcpListener socket = new TcpListener(localAddr, 5672); 
socket.Start(); 
Console.Write("Waiting for a connection... "); 

// Perform a blocking call to accept requests. 
TcpClient client = socket.AcceptTcpClient(); 
Console.WriteLine("Connected to client!"); 

et moi avons deux clients qui envoient un octet. Le client A envoie 0x1 et le client B envoie 0x2. Du côté du serveur, je lis ces données comme ceci:

Byte[] bytes = new Byte[256]; 
String data = null; 

NetworkStream stream = client.GetStream(); 
while ((stream.Read(bytes, 0, bytes.Length)) != 0) 
{ 
    byte[] answer = new ... 
    stream.Write(answer , 0, answer.Length); 
} 

client A envoie 0x11. J'ai besoin d'un moyen de savoir que ce client est le même que celui qui a envoyé "0x1" auparavant.

Répondre

4

Chaque instance TcpClient est destinée à une connexion différente. Une connexion dans TCP se compose de quatre choses: IP source, port source, IP cible, port cible. Ainsi, même si vous avez la même adresse IP et le même port cible, et le même port source, vous avez deux connexions différentes.

Les données envoyées par un client ne seront pas mélangées aux données envoyées par l'autre client. Les données envoyées par un client sur une connexion seront reçues dans l'ordre sur cette connexion.

Le seul moment où les sessions deviennent un problème est de se souvenir du client après la fermeture de la connexion.

+0

Je n'ai pas compris comment les données ne seront pas mélangées. Après avoir lu les données envoyées par le premier client, l'objet TcpClient est détruit. Et pour lire les données suivantes je dois faire socket.AcceptTcpClient(); encore. Pouvez-vous poster un code de démo qui détecte quand le client A envoie 0x11 après sendig 0x1? Merci –

+0

@ZeCarlos: avez-vous vraiment besoin de fermer les instances 'TcpClient'? Pourquoi ne pas les réutiliser? Chacun serait en mesure de vous obtenir un flux de données non corrompu d'exactement un client. –

+0

Vous avez raison. Je peux réutiliser TcpClient et son flux associé. Désolé pour mon ignorance. Merci –

0

Vous devrez probablement implémenter votre propre protocole afin d'identifier les clients. Peut-être définir un morceau d'octets, où en plus des données, vous incluez également un identifiant client.

+0

Merci pour votre réponse, mais je ne peux pas le faire. J'implémente un protocole qui communique sur TCP. Je ne peux pas modifier les informations envoyées par les clients. –

+0

@ZeCarlos: alors qui définit le format des données envoyées par les clients? –

+0

C'est un protocole. AMQP ce cas. http://www.amqp.org/confluence/download/attachments/720900/amqp0-9.pdf?version = 1 & modificationDate = 1183135701000 Mais les données dans les cadres n'ont pas de champ identifiant le client. Je m'identifie comme étant fait en connaissant l'ip et le port utilisé par le client. Je suis à la recherche d'une façon dont cela est fait automatiquement –

0

Vous aurez besoin d'un type d'authentification ou d'un jeton pré-négocié, et tout cela en quelque sorte crypté avec un peu de sel.

+1

Vous n'aurez certainement pas besoin de hachage salé ou de cryptage pour les moyens d'identification, mais en fonction des besoins particuliers, il pourrait être recommandé. –

1

Il existe beaucoup de documentation sur la façon dont les sessions sont implémentées dans le monde Web (HTTP).

Une clé est de savoir si vous fermez les connexions clientes, ou sont-elles persistantes? Si elles sont persistantes, identifiez-les simplement par leur référence d'objet. Si non, alors ...

1) Vous pouvez effectuer des sessions simples en fonction de l'adresse IP source. Mais si plusieurs clients sont derrière un pare-feu NAT, partageant l'adresse IP, cela ne fonctionne pas, voir l'option suivante.

2) Utilisez un "cookie"

3) Utiliser l'authentification pour identifier chaque client

Toutes les options sauf sessions basées sur IP nécessite d'ajouter quelque chose au protocole lui-même.

Certaines choses à retenir avec les prises. Le port distant IP + distant identifie de manière unique un socket TCP client. Plusieurs connexions provenant du même client distant auront des ports distants différents. Mais vous ne pouvez pas compter sur cela si le socket se ferme, car le système d'exploitation distant peut recycler le port distant pour une nouvelle connexion une fois que l'ancien est arrivé à expiration.

Questions connexes