Comment faire pour utiliser le protocole TCP client/auditeur en multithread c#?
J'ai écrit ce code pour mon serveur:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
private static bool terminate;
public static bool Terminate
{
get { return terminate; }
}
private static int clientNumber = 0;
private static TcpListener tcpListener;
static void Main(string[] args)
{
StartServer();
Console.Read();
}
private static void StartServer()
{
try
{
Console.WriteLine("Server starting...");
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8000);
terminate = false;
tcpListener.Start();
tcpListener.BeginAcceptTcpClient(ConnectionHandler, null);
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("Server stopping...");
terminate = true;
if (tcpListener != null)
{
tcpListener.Stop();
}
}
}
private static void ConnectionHandler(IAsyncResult result)
{
TcpClient client = null;
try
{
client = tcpListener.EndAcceptTcpClient(result);
}
catch (Exception)
{
return;
}
tcpListener.BeginAcceptTcpClient(ConnectionHandler, null);
if (client!=null)
{
Interlocked.Increment(ref clientNumber);
string clientName = clientNumber.ToString();
new ClientHandler(client, clientName);
}
}
}
}
class ClientHandler
{
private TcpClient client;
private string ID;
internal ClientHandler(TcpClient client, string ID)
{
this.client = client;
this.ID = ID;
Thread thread = new Thread(ProcessConnection);
thread.IsBackground = true;
thread.Start();
}
private void ProcessConnection()
{
using (client)
{
using (BinaryReader reader=new BinaryReader(client.GetStream()))
{
if (reader.ReadString()==Responses.RequestConnect)
{
using (BinaryWriter writer=new BinaryWriter(client.GetStream()))
{
writer.Write(Responses.AcknowledgeOK);
Console.WriteLine("Client: "+ID);
string message = string.Empty;
while (message!=Responses.Disconnect)
{
try
{
message = reader.ReadString();
}
catch
{
continue;
}
if (message==Responses.RequestData)
{
writer.Write("Data Command Received");
}
else if (message==Responses.Disconnect)
{
Console.WriteLine("Client disconnected: "+ID);
}
else
{
Console.WriteLine("Unknown Command");
}
}
}
}
else
{
Console.WriteLine("Unable to connect client: "+ID);
}
}
}
}
}
class Responses
{
public const string AcknowledgeOK = "OK";
public const string AcknowledgeCancel = "Cancel";
public const string Disconnect = "Bye";
public const string RequestConnect = "Hello";
public const string RequestData = "Data";
}
ce code écouter les demandes des clients dans un environnement multi threaded. Je suis incapable de comprendre comment les distinguer entre les différents clients connectés à mon ce serveur et le client qui est de la déconnexion et de la demande pour les différentes commandes.
mon code client est:
private static void clietnRequest(string message,ref string response)
{
using (TcpClient client = new TcpClient())
{
if (!client.Connected)
{
client.Connect(IPAddress.Parse("127.0.0.1"), 8000);
using (NetworkStream networkStream = client.GetStream())
{
using (BinaryWriter writer = new BinaryWriter(networkStream))
{
writer.Write(Responses.RequestConnect);
using (BinaryReader reader = new BinaryReader(networkStream))
{
if (reader.ReadString() == Responses.AcknowledgeOK)
{
response = Responses.AcknowledgeOK;
}
}
}
}
}
}
}
ce morceau de code se connecte le client vers le serveur, mais je n'arrive pas à envoyer plus de messages. Je veux dans mon application si le client est connecté, il peut envoyer des commandes au serveur. au lieu de le faire à chaque fois un nouveau client vers le serveur. Il me manque quelque chose ici, de bien vouloir me guider dans la bonne direction. Je suis totalement novice en c# programmation réseau. De bien vouloir m'aider à améliorer mon code. D'écoute Tcp et le protocole Tcp Client est valide pour ce scénario, ou dois-je utiliser des Sockets?
return
vous n'avez aucune idée de si quelque chose allait mal, au moins les mettre dans une certaine forme de l'enregistrement.ses juste pour la démo fin,
C'est encore une mauvaise habitude qui est bon pour briser tôt. Sur une note séparée, pourquoi êtes-vous à l'aide d'un
ref
au lieu de simplement en passant la réponse à la valeur de retour?voir: stackoverflow.com/questions/5834755/...
OriginalL'auteur user1941098 | 2013-01-10
Vous devez vous connecter pour publier un commentaire.
Vous êtes à la fermeture de la connexion à chaque fois côté client, après l'envoi d'un message, si vous voulez faire cela, il n'y a rien de mal à cela, mais vous aurez besoin d'envoyer une certaine forme d'identification pour le serveur de sorte qu'il peut dire que ce n'est pas une nouvelle connexion, mais une vieille connexion connexion en un deuxième temps. C'est EXACTEMENT ce que le
HTTP
protocole est en train de faire et que "l'identification" sont les cookies d'internet.Que la première option est très bien si vous transmettez des données très rarement, mais si vous le faites plus souvent, vous avez besoin de garder la connexion ouverte.
Bref si vous avez besoin de prendre la loi de la connexion et de la déconnexion de la demande du client de la fonction et de passer la connexion ouverte comme un argument.
En le faisant de cette manière, le
client
objet côté serveur représente le client, vous disposez d'une seule instance de chaque client connecté et restera associé avec le client jusqu'à ce qu'il se déconnecte. Si vous souhaitez effectuer le suivi de tous les clients connectés, vous aurez besoin de les insérer tous à certains de la collection comme unList<TcpClient>
(soit utiliser un La Collecte Simultanée ou utiliser le verrouillage parce que vous êtes en multi-thread) et ensuite vous aurez une liste de tous les clients (vous aurez besoin d'avoir les clients de nettoyer après eux-mêmes afin de se retirer de la liste après une déconnexion).Je suis en supposant que
clientRequest
est appelée à partir de l'intérieur d'une certaine forme de boucle. Vous créez la connexion avant la boucle et fermer après la boucle se termine.OriginalL'auteur Scott Chamberlain