El siguiente programa de ejemplo implementa una comunicación Socket simple y puede abrir múltiples clientes. La prueba local pasó, pero no se realizó ninguna prueba en línea.
Servidor:
usando System.Net;
usando System.Net.Sockets;
usando
System.Threading
;
espacio de nombres MySocketServer1
{
clase parcial pública Form1 : Formulario
{
dirección IP privada serverIP = IPAddress.Parse("127.0.0.1");// Utilice esta máquina para probar
el servidor IPEndPoint privadoFullAddr;// Dirección de terminal completa
Private Socket sock
; Timer myTimer;
private ArrayList alSock;// Se utiliza para guardar conexiones cuando se establecen varias conexiones.
Formulario público1()
{
InicializarComponente()
;
private void btStart_Click(object sender, EventArgs e)
{
serverFullAddr = new IPEndPoint(serverIP, 1000); //Obtenga el número de puerto 1000
//Construya el objeto Socket, el tipo de socket es "stream socket", especifique la tupla de cinco elemento de protocolo
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
// Especifique el binario local en la tupla de cinco, es decir, la dirección del host local y el número de puerto
sock.Bind
(serverFullAddr);
/Listen Si hay una conexión entrante, especifique que el valor máximo de la cola de conexiones pendientes sea 20
sock.Listen(20);
alSock = nueva ArrayList();
// Construya un temporizador con un intervalo de tiempo de 1 segundo, es decir, ejecute el método aceptar () cada segundo para obtener la primera solicitud de conexión pendiente en la cola de solicitudes de conexión
myTimer =new System.Timers.Timer(1000)
; Transcurrido +=nuevo System.Timers.ElapsedEventHandler(myTimer_Elapsed);
myTimer.Enabled = verdadero
;
private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
myTimer.Enabled = false;
//Ejecutar aceptar(), este hilo se bloqueará cuando la cola de suspensión esté vacía y el temporizador se detendrá debido a la declaración anterior , hasta // hasta que se pase una conexión al
Socket AcceptSock = sock.Accept();
// Almacene el objeto Socket generado por Accept() en ArrayList
alSock.Add(acceptSock);
// Construya el objeto Threading.Timer, lo que hará que el programa inicie otro hilo. El hilo ejecutará la función de devolución de llamada y los parámetros de la función // límite delegado deben ser de tipo objeto. El segundo parámetro del constructor Threading.Timer es el parámetro pasado a la función de devolución de llamada; // El tercer parámetro especifica el retraso antes de llamar a la función de devolución de llamada; si es 0, comenzará inmediatamente; la función de devolución de llamada // Intervalo, si se establece en 0, solo se ejecutará una vez.
System.Threading.Timer ti = new System.Threading.Timer(new
TimerCallback(ReceiveMsg), AcceptSock, 0, 0);
myTimer.Enabled = true
;
private void RecibirMsg(object obj)
{
Socket aceptarSock = (Socket)obj;
intentar
{
while (true)
{
byte[] byteArray = new byte[100];
//Recibir datos
//Convertir byte Convertir la matriz en una
cadena strRec = System.Text.Encoding.UTF8.GetString(byteArray);
if (this.rtbReceive.InvokeRequired)
{
this.rtbReceive.Invoke(new EventHandler(this.ChangeRickTextBox), new
object[] { strRec, EventArgs.Empty });
}
}
}
catch(Excepción ex)
{
aceptarSock.Close();
MessageBox.Show
("S:Error de mensaje de recepción"+ex.Mensaje)
;
vacío privado ChangeRickTextBox (objeto obj, EventArgs e)
{
cadena s = System.Convert.ToString (obj);
this.rtbReceive.AppendText (s + Environment.NewLine)
;
private void btSend_Click(remitente
del
objeto
, EventArgs e)
{
Socket sc=null;
byte[] byteSend =
System.Text.Encoding.UTF8.GetBytes(this.tbSend.Text.ToCharArray
());
al mismo tiempo Cuando el cliente se conecta, ingrese qué conexión enviar en textBox1
int index=
int.Parse(this.textBox1.Text.Trim()
)
;
.Send(byteSend);
}
catch(Exception ex)
{
if(sc!= null)
{
sc.Close()
}
MessageBox.Show
("S:Error de mensaje de envío"+ex.Message)
;
btClose_Click
vacío privado (remitente del objeto, EventArgs e)
{
prueba
{
Application.Exit()
}
catch (Excepción ex)
{
MessageBox.Show
("S: Error de cierre de socket" + ex.Message)
== =
)
;
= == == == == == == == == == == == == == == == == == == == == == == == = = = = == == == ==
Cliente:
usando System.Net;
usando System.Net.Sockets;
usando System.Threading;
espacio de nombres MySocketClient1
{
clase parcial pública Form1 : Formulario
{
dirección IP privada serverIP = IPAddress.Parse ("127.0.0.1");
servidor IPEndPoint privadoCalcetín
de socket privado;
Formulario público1()
{
InicializarComponente()
;
btConnect_Click vacío privado (remitente del objeto, EventArgs e)
{
prueba
{
serverFullAddr = new IPEndPoint (serverIP, 1000);
sock
= new Socket (AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
Establecer una conexión con el host remoto
// Iniciar un nuevo hilo para recibir datos
Thread t = new Thread(new ThreadStart(ReceiveMsg));
t.Name = "Receive Message"
// Un hilo es un hilo en segundo plano o en primer plano. Los subprocesos en segundo plano son similares a los subprocesos en primer plano, excepto que el subproceso en segundo plano // no impide que el proceso finalice. Una vez que todos los subprocesos en primer plano que pertenecen a un proceso han terminado, Common Language Runtime // finaliza el proceso llamando a Abort en cualquier subproceso en segundo plano que todavía esté activo.
t.IsBackground = verdadero;
t.Start();
catch
(Excepción ex)
{
MessageBox.Show
(ex.Mensaje)
;
privado vacío RecibirMsg()
{
intentar
{
mientras (verdadero)
{
byte[]byteRec
= nuevo byte[100];
this.sock.Receive(byteRec
cadena = System.Text.Encoding.UTF8.GetString(byteRec);
(this.rtbReceive.InvokeRequired)
{
this.rtbReceive.Invoke(new EventHandler(ChangeRtb), new object[]
{ strRec, EventArgs.Empty });
}
}
}
catch(Exception ex)
{
MessageBox.Show("Recibir mensaje de error "+ex.Mensaje);
}
}
Private void ChangeRtb(objeto obj, EventArgs e)
{
cadena s = System.Convert.ToString(obj);
this.rtbReceive.AppendText(s + Environment.NewLine)
;
btSend_Click vacío privado (remitente del objeto, EventArgs e)
{
byte[] byteSend =
System.Text.Encoding.UTF8.GetBytes(this.tbSend.Text.ToCharArray());
intente
{
this.sock.Send(byteSend}
catch
)
;{
MessageBox.Show ("Error de envío de mensaje"
)
;
btClose_Click vacío privado (remitente del objeto, EventArgs e)
{
intente
{
this.sock.Shutdown (SocketShutdown.Receive);
this.sock.Close()
Application.Exit()
;
catch
{
MessageBox.Show ("Error de salida") ;
} }
}
}
Rompecabezas
:
La declaración marcada en rojo en el lado del cliente: this.sock.Shutdown(SocketShutdown.Receive), si se cambia a
this.sock.Shutdown(SocketShutdown.Both); Enviar);
luego, cuando se hace clic en el botón Cerrar, el uso de la CPU se dispara al 100%. Sin embargo, usar this.sock.Shutdown(SocketShutdown.Receive)
o no llamar al método Shutdown() no tiene este problema. ¿No debería el cliente utilizar Shutdown()?
http://www.cnblogs.com/KissKnife/archive/2006/08/13/475707.html