L'exemple de programme suivant implémente une communication Socket simple et peut ouvrir plusieurs clients. Le test local a réussi, mais aucun test en ligne n'a été effectué.
Serveur :
en utilisant System.Net ;
en utilisant System.Net.Sockets ;
en utilisant System.Threading
;
espace de noms MySocketServer1
{
public partial class Form1 : Form
{
private IPAddress serverIP = IPAddress.Parse("127.0.0.1");//Utilisez cette machine pour tester
le serveur IPEndPoint privéFullAddr;//Adresse complète du terminal
private Socket sock;
private System.Timers. Timer myTimer ;
private ArrayList alSock ;//Utilisé pour enregistrer les connexions lorsque plusieurs connexions sont établies
public Form1()
{
InitializeComponent()
;
private void btStart_Click(object sender, EventArgs e)
{
serverFullAddr = new IPEndPoint(serverIP, 1000); //Obtenir le numéro de port 1000
//Construire l'objet Socket, le type de socket est "stream socket", spécifier le cinq-tuple Le élément de protocole
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
//Spécifiez le binaire local dans le cinq-tuple, c'est-à-dire l'adresse de l'hôte local et le numéro de port
sock.Bind
(serverFullAddr);
/Listen S'il y a une connexion entrante, spécifiez que la valeur maximale de la file d'attente de connexion en attente est de 20
sock.Listen(20);
alSock = new ArrayList();
//Construisez un minuteur avec un intervalle de temps de 1 seconde, c'est-à-dire exécutez la méthode accept() toutes les secondes pour obtenir la première demande de connexion en attente dans la file d'attente des demandes de connexion
myTimer =new System.Timers.Timer(1000 )
; Elapsed +=new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
myTimer.Enabled = true
}
private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
myTimer.Enabled = false;
//Exécuter accept(), ce thread sera bloqué lorsque la file d'attente de suspension est vide et le minuteur s'arrêtera en raison de l'instruction précédente , jusqu'à ce qu'une connexion soit passée dans
le Socket acceptSock = sock.Accept();
// Stocke l'objet Socket généré par accept() dans ArrayList
alSock.Add(acceptSock);
// Construit l'objet Threading.Timer, ce qui amènera le programme à démarrer un autre thread. Le thread exécutera la fonction de rappel et les paramètres de la limite déléguée // de la fonction doivent être de type objet. Le deuxième paramètre du constructeur Threading.Timer est le paramètre passé dans la fonction de rappel ; //Le troisième paramètre spécifie le délai avant l'appel de la fonction de rappel, s'il est 0, il démarrera immédiatement ; le dernier paramètre spécifie l'heure d'appel ; la fonction de rappel // Intervalle, si elle est définie sur 0, elle ne sera exécutée qu'une seule fois.
System.Threading.Timer ti = new System.Threading.Timer(new
TimerCallback(ReceiveMsg)
, acceptSock, 0, 0)
;
private void ReceiverMsg(object obj)
{
Socket acceptSock = (Socket)obj;
try
{
while (true)
{
byte[] byteArray = new byte[100];
acceptSock.Receive(byteArray);//Recevoir des données
//Convertir l'octet Convertir le tableau dans une
chaîne strRec = System.Text.Encoding.UTF8.GetString(byteArray);
if (this.rtbReceive.InvokeRequired)
{
this.rtbReceive.Invoke(new EventHandler(this.ChangeRickTextBox), new
object[] { strRec , EventArgs.Empty });
}
}
}
catch(Exception ex)
{
acceptSock.Close();
MessageBox.Show("S:Receive Message Error"+ex.Message
)
;
private void ChangeRickTextBox(object obj,EventArgs e)
{
string s = System.Convert.ToString(obj);
this.rtbReceive.AppendText(s + Environment.NewLine })
;
private void btSend_Click(object sender, EventArgs e)
{
Socket
sc
=null;
byte[] byteSend =
System.Text.Encoding.UTF8.GetBytes(this.tbSend.Text.ToCharArray
());
en même temps Lorsque le client se connecte, entrez la connexion à envoyer dans textBox1
int
index = int.Parse(this.textBox1.Text.Trim());
sc
= (Socket)alSock[index - 1];
.Send(byteSend);
}
catch(Exception ex)
{
if(sc != null)
{
sc.Close();
}
MessageBox.Show("S:Envoyer une erreur de message"+ex.Message
)
;
private void btClose_Click
(
expéditeur d'objet, EventArgs e)
{
try
{
Application.Exit();
}
catch
(Exception ex)
{
MessageBox.Show("S:Close Socket Error" +
ex.Message
)
;
= == == == == == == == == == == == == == == == == == == == == == == == = = = = == == == ==
Client :
en utilisant System.Net ;
en utilisant System.Net.Sockets
en utilisant System.Threading ;
espace de noms MySocketClient1
{
classe partielle publique Form1 : Form
{
private IPAddress serverIP = IPAddress.Parse("127.0.0.1");
private IPEndPoint serverFullAddr
;
public Form1()
{
InitializeComponent()
;
private void btConnect_Click
(
expéditeur d'objet, EventArgs e)
{
try
{
serverFullAddr
= new IPEndPoint (serverIP, 1000);
// Établir une connexion à l'hôte distant
//Démarrez un nouveau thread pour recevoir des données
Thread t = new Thread(new ThreadStart(ReceiveMsg));
t.Name = "Receive Message";
//Un thread est soit un thread d'arrière-plan, soit un thread de premier plan. Les threads d'arrière-plan sont similaires aux threads de premier plan, sauf que le thread d'arrière-plan // n'empêche pas le processus de se terminer. Une fois que tous les threads de premier plan appartenant à un processus sont terminés, le Common Language Runtime // termine le processus en appelant Abort sur tous les threads d'arrière-plan encore actifs.
t.IsBackground = true;
t.Start();
}
catch(Exception ex)
{
MessageBox.Show
(ex.Message)
;
private
void
ReceiverMsg()
{
try
{
while (true)
{
byte[] byteRec = new byte[100];
this.sock.Receive(byteRec)
;
(this.rtbReceive.InvokeRequired)
{
this.rtbReceive.Invoke(new EventHandler(ChangeRtb)
,
new object[]
{ strRec, EventArgs.Empty });
catch
(Exception ex)
{
MessageBox.Show("Recevoir une erreur de message "+ex.Message);
}
}
private void ChangeRtb(object obj, EventArgs e)
{
string s = System.Convert.ToString(obj);
this.rtbReceive.AppendText(s + Environment.NewLine })
;
private void btSend_Click (expéditeur d'objet, EventArgs e)
{
byte[] byteSend =
System.Text.Encoding.UTF8.GetBytes(this.tbSend.Text.ToCharArray());
try
{
this.sock.Send(byteSend
}
catch
);{
MessageBox.Show
("Envoyer un message d'erreur")
;
private void btClose_Click (expéditeur d'objet, EventArgs e)
{
try
{
this.sock.Shutdown (SocketShutdown.Receive);
this.sock.Close ();
Application.Exit ()
;
catch
{
MessageBox.Show ("Erreur de sortie") ;
} }
}
}
Puzzle
:
L'instruction marquée en rouge côté client : this.sock.Shutdown(SocketShutdown.Receive), si elle est remplacée par
this.sock.Shutdown(SocketShutdown.Both); Send);
puis lorsque vous cliquez sur le bouton Fermer, l'utilisation du processeur monte en flèche à 100%. Cependant, utiliser this.sock.Shutdown(SocketShutdown.Receive)
; Le client ne devrait-il pas utiliser Shutdown() ?
http://www.cnblogs.com/KissKnife/archive/2006/08/13/475707.html