Das folgende Beispielprogramm implementiert eine einfache Socket-Kommunikation und kann mehrere Clients öffnen. Der lokale Test wurde bestanden, es wurde jedoch kein Online-Test durchgeführt.
Server:
mit System.Net;
mit System.Net.Sockets;
mit System.Threading
;
namespace MySocketServer1
{
public partial class Form1 : Form
{
private IPAddress serverIP = IPAddress.Parse("127.0.0.1");//Diese Maschine zum Testen
privater IPEndPoint serverFullAddr;//Vollständige Terminaladresse
private Socket
private System.Timers. Timer myTimer;
private ArrayList alSock;//Wird zum Speichern von Verbindungen verwendet, wenn mehrere Verbindungen hergestellt werden
public Form1()
{
InitializeComponent(
}
private void btStart_Click(object sender, EventArgs e)
{
serverFullAddr = new IPEndPoint(serverIP, 1000); //Erhalten Sie die Portnummer 1000
//Konstruieren Sie das Socket-Objekt, der Socket-Typ ist „Stream Socket“, geben Sie das Fünf-Tupel an Protokollelement
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
Geben Sie die lokale Binärdatei im Fünf-
Tupel an, dh die lokale Hostadresse und die Portnummer
sock.Bind(serverFullAddr);
/Listen Gibt an, ob eine eingehende Verbindung vorliegt, und geben Sie den Maximalwert der ausstehenden Verbindungswarteschlange auf 20 an.
sock.Listen(20);
alSock = new ArrayList();
//Erstelle einen Timer mit einer Zeitlücke von 1 Sekunde, d. h. führe die Methode „accept()“ jede Sekunde aus, um die erste ausstehende Verbindungsanforderung in der Verbindungsanforderungswarteschlange zu erhalten
myTimer =new System.Timers.Timer(1000 )
; Elapsed +=new System.Timers.ElapsedEventHandler(myTimer_Elapsed
= true
;
private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
myTimer.Enabled = false;
//Accept() ausführen, dieser Thread wird blockiert, wenn die Suspendierungswarteschlange leer ist, und der Timer wird aufgrund der vorherigen Anweisung angehalten
,
bis//
bis eine Verbindung an
den Socket
übergeben wird;
Dies führt dazu, dass das Programm einen anderen Thread startet. Der Thread führt die Rückruffunktion aus und die Funktionsparameter des Delegate-Limits müssen vom Objekttyp sein. Der zweite Parameter des Threading.Timer-Konstruktors ist der an die Rückruffunktion übergebene Parameter. // Der dritte Parameter gibt die Verzögerung vor dem Aufruf der Rückruffunktion an. Wenn er 0 ist, gibt der letzte Parameter die Aufrufzeit an die Rückruffunktion // Intervall, wenn auf 0 gesetzt, wird sie nur einmal ausgeführt.
System.Threading.Timer ti = new System.Threading.Timer(new
TimerCallback(
ReceiveMsg)
, takeSock, 0, 0);
private void ReceiveMsg(object obj)
{
Socket AcceptSock = (Socket)obj;
try
{
while (true)
{
byte[] byteArray = new byte[100];
//Receive data
//Convert by byte Convert das Array in einen
String strRec = System.Text.Encoding.UTF8.GetString(byteArray);
if (this.rtbReceive.InvokeRequired)
{
this.rtbReceive.Invoke(new EventHandler(this.ChangeRickTextBox), new
object[] { strRec ,
EventArgs.Empty
}
)
;
private void ChangeRickTextBox(object obj,EventArgs e)
{
string s = System.Convert.ToString(obj
)
;
private void btSend_Click(object sender, EventArgs e)
{
Socket sc=null
byte[] byteSend =
System.Text.Encoding.UTF8.GetBytes(this.tbSend.Text.ToCharArray());
try
{
//Es gibt mehrere bei Geben Sie gleichzeitig beim Herstellen einer Verbindung durch den Client ein, welche Verbindung gesendet werden soll: textBox1
int index = int.Parse(this.textBox1.Text.Trim());
sc = (Socket)alSock[index - 1];
//Send data
sc .Send(byteSend);
}
Catch(Exception ex)
{
if(sc != null)
{
sc.Close(
}
MessageBox.Show("S:Send Message Error"+ex.Message
)
;
private void btClose_Click(object sender, EventArgs e)
{
try
{
Application.Exit();
}
Catch (Exception ex)
{
MessageBox.Show
(
"S
:Close Socket Error" + ex.Message
)
;
= == == == == == == == == == == == == == == == == == == == == == == == = = = = == == == ==
Client:
mit System.Net;
mit System.Net.Sockets
mit System.Threading;
namespace MySocketClient1
{
public partial class Form1 : Form
{
private IPAddress serverIP = IPAddress.Parse("127.0.0.1");
private IPEndPoint serverFullAddr
;
public Form1()
{
InitializeComponent(
}
private void btConnect_Click(object sender, EventArgs e)
{
try
{
serverFullAddr = new IPEndPoint(serverIP, 1000);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
// Stellen Sie eine Verbindung zum Remote-Host her
//Neuen Thread starten, um Daten zu empfangen
Thread t = new Thread(new ThreadStart(ReceiveMsg));
t.Name = "Receive Message";
//Ein Thread ist entweder ein Hintergrund-Thread oder ein Vordergrund-Thread. Hintergrundthreads ähneln Vordergrundthreads, mit der Ausnahme, dass der Hintergrundthread // nicht die Beendigung des Prozesses verhindert. Sobald alle zu einem Prozess gehörenden Vordergrund-Threads beendet wurden, beendet die Common Language Runtime // den Prozess, indem sie „Abort“ für alle noch aktiven Hintergrund-Threads aufruft.
t.IsBackground = true;
t.Start();
}
Catch(Exception ex)
{
MessageBox.Show
(ex.Message)
;
private void ReceiveMsg()
{
try
{
while
(true)
{
byte[] byteRec = new byte[100
]
;
(this.rtbReceive.InvokeRequired)
{
this.rtbReceive.Invoke(new EventHandler(ChangeRtb), new object[]
{ strRec, EventArgs.Empty });
}
}
}
Catch(Exception ex)
{
MessageBox.Show("Receive Message Error "+ex.Message);
}
}
private void ChangeRtb(object obj, EventArgs e)
{
string
s = System.Convert.ToString(obj)
;
private void btSend_Click(object sender, EventArgs e)
{
byte[] byteSend =
System.Text.Encoding.UTF8.GetBytes(
this.tbSend.Text.ToCharArray());
try
{
this.sock.Send(byteSend)
;
{
MessageBox.Show
("Fehler beim Senden der Nachricht")
;
private void btClose_Click(object sender, EventArgs
e
)
{
try
{
this.sock.Shutdown
(
SocketShutdown.Receive
)
;
;
} }
}
}
Puzzle
:
Die rot markierte Anweisung auf der Clientseite: this.sock.Shutdown(SocketShutdown.Receive), wenn sie in
this.sock.Shutdown(SocketShutdown.Both) geändert wird;
Wenn Sie dann auf die Schaltfläche „Schließen“
klicken, steigt die CPU-Auslastung auf 100 %.
Dieses Problem tritt jedoch nicht auf, wenn Sie this.sock.Shutdown(SocketShutdown.Receive); verwenden. Sollte der Client nicht Shutdown() verwenden?
http://www.cnblogs.com/KissKnife/archive/2006/08/13/475707.html