The following example program implements simple Socket communication and can open multiple clients. The local test passed, but no online test was done.
Server:
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;
namespace MySocketServer1
{
public partial class Form1 : Form
{
private IPAddress serverIP = IPAddress.Parse("127.0.0.1");//Use this machine for testing
private IPEndPoint serverFullAddr;//Full terminal address
private Socket sock;
private System.Timers. Timer myTimer;
private ArrayList alSock;//Used to save connections when multiple connections are established
public Form1()
{
InitializeComponent();
}
private void btStart_Click(object sender, EventArgs e)
{
serverFullAddr = new IPEndPoint(serverIP, 1000); //Get the port number 1000
//Construct the Socket object, the socket type is "stream socket", specify the five-tuple The protocol element
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
//Specify the local binary in the five-tuple, that is, the local host address and port number
sock.Bind(serverFullAddr);
//Listen Whether there is an incoming connection, specify the maximum value of the pending connection queue to be 20
sock.Listen(20);
alSock = new ArrayList();
//Construct a timer with a time gap of 1 second, that is, execute the accept() method every second to obtain the first pending connection request in the connection request queue
myTimer =new System.Timers.Timer(1000 );
myTimer.Elapsed +=new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
myTimer.Enabled = true;
}
private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
myTimer.Enabled = false;
//Execute accept(), this thread will be blocked when the suspension queue is empty, and the timer will stop due to the previous statement , until // until a connection is passed into
the Socket acceptSock = sock.Accept();
// Store the Socket object generated by accept() into the ArrayList
alSock.Add(acceptSock);
// Construct the Threading.Timer object, which will cause the program to Start another thread. The thread will execute the callback function, and the delegate limit //function parameters must be of object type. The second parameter of the Threading.Timer constructor is the parameter passed into the callback function; //The third parameter specifies the delay before calling the callback function, if it is 0, it will start immediately; the last parameter specifies the time to call the callback function // Interval, if set to 0, it will only be executed once.
System.Threading.Timer ti = new System.Threading.Timer(new
TimerCallback(ReceiveMsg), acceptSock, 0, 0);
myTimer.Enabled = true;
}
private void ReceiveMsg(object obj)
{
Socket acceptSock = (Socket)obj;
try
{
while (true)
{
byte[] byteArray = new byte[100];
acceptSock.Receive(byteArray);//Receive data
//Convert byte Convert the array into a
string 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());
try
{
//There are several at the same time When the client connects, enter which connection to send in 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:
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace MySocketClient1
{
public partial class Form1 : Form
{
private IPAddress serverIP = IPAddress.Parse("127.0.0.1");
private IPEndPoint serverFullAddr;
private Socket sock;
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);
sock.Connect(serverFullAddr);// Establish a connection to the remote host
//Start a new thread to receive data
Thread t = new Thread(new ThreadStart(ReceiveMsg));
t.Name = "Receive Message";
//A thread is either a background thread or a foreground thread. Background threads are similar to foreground threads, except that the background thread // does not prevent the process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime // ends the process by calling Abort on any background threads that are still active.
t.IsBackground = true;
t.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ReceiveMsg()
{
try
{
while (true)
{
byte[] byteRec = new byte[100];
this.sock.Receive(byteRec);
string strRec = System.Text.Encoding.UTF8.GetString(byteRec);
if (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);
this.rtbReceive.AppendText(s + Environment.NewLine);
}
private void btSend_Click(object sender, EventArgs e)
{
byte[] byteSend =
System.Text.Encoding.UTF8.GetBytes(this.tbSend.Text.ToCharArray());
try
{
this.sock.Send(byteSend);
}
catch
{
MessageBox.Show("Send Message Error");
}
}
private void btClose_Click(object sender, EventArgs e)
{
try
{
this.sock.Shutdown(SocketShutdown.Receive);
this.sock.Close();
Application.Exit();
}
catch
{
MessageBox.Show("Exit Error") ;
} }
}
}
Puzzle
:
The red marked statement on the client side: this.sock.Shutdown(SocketShutdown.Receive), if changed to
this.sock.Shutdown(SocketShutdown.Both); or this.sock.Shutdown(SocketShutdown. Send);
then when the Close button is clicked, the CPU usage skyrockets to 100%. However, using this.sock.Shutdown(SocketShutdown.Receive);
or not calling the Shutdown() method does not have this problem. Shouldn't the client use Shutdown()?
http://www.cnblogs.com/KissKnife/archive/2006/08/13/475707.html