同步編程使用的情況不多,在以下3種情況下可以使用同步:
1.客戶端數量較少情況下的服務端編程
2.客戶端數量較多,但都是短連接情況下的服務端編程
3.客戶端編程
以下主要針對服務端編程的2種情況,分別做一示例,以下示例均使用tcp協議.
1.在客戶端數量較少的情況下,
数量较少是指会同时连接到服务器的客户端数量一般在50人以下。这种情况下我们可以考虑使用同步Socket+Thread来实现我们的服务端。这样会让我们编写逻辑更清晰的代码而性能不会下降太多。
首先创建一个Socket,并且给它绑定一个EndPoint后开始监听。接下来我们创建一个线程,在这个线程中我们用一个无限循环来接收来自客户端的连接请求。在接收到一个请求后,为这个客户端创建一个新的线程,并且在这个线程中也使用一个无限循环接收来自这个客户端的数据
private Socket listener;
{
// 建立socket偵聽連接
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint locEP = new IPEndPoint(IPAddress.Any, 2000 );
listener.Bind(locEP);
listener.Listen( 100 );
// 建立一個線程處理連接請求
Thread acceptThread = new Thread( new ThreadStart(AcceptWorkThread));
acceptThread.Start();
}
private void AcceptWorkThread()
{
Thread.CurrentThread.IsBackground = true ;
while ( true )
{
Socket accept = listener.Accept();
IPEndPoint remoEP = (IPEndPoint)accept.RemoteEndPoint;
// string recString = "接收到来自" + remoEP.Address.ToString() + "的连接。";
// this.Invoke(new AddListItemHandler(this.AddListItem), new string[] { recString });
// 為客戶端請求建立新的線程
Thread receiveThread = new Thread( new ParameterizedThreadStart(ReceiveWorkThread));
receiveThread.Start(accept);
}
}
// 接收數據
private void ReceiveWorkThread( object obj)
{
Thread.CurrentThread.IsBackground = true ;
Socket socket = (Socket)obj;
byte [] buffer = new byte [ 1024 ];
while ( true )
{
int receiveCount = socket.Receive(buffer);
if (receiveCount > 0 )
{
IPEndPoint remoEP = (IPEndPoint)socket.RemoteEndPoint;
// string recString = "来自客户端" + remoEP.Address.ToString() + "的消息:" + Encoding.Default.GetString(buffer, 0, receiveCount);
// this.Invoke(new AddListItemHandler(this.AddListItem), new string[] { recString });
socket.Send(buffer, receiveCount, SocketFlags.None);
}
else
{
socket.Close();
break ;
}
}
}
2.客戶端數量較多,但都是短連接的情況下,
短连接是指客户端的连接在处理完一次收发之后就产即断开的场景,比如说HTTP协议就是一种短连接。HTTP在客户端发出请求时建立一个Socket连接,并通过Socket发出一个URL请求,服务端在处理完这个请求并回发相应的页面后便会断开这个连接。那么在这种场景下我们也可以使用同步Socket来实现我们的需求。
以下示例方案中每一个连接都是短连接。而且顺序都是固定的。都是:接入->接收->发送这样的顺序,那么我们就可以在一个方法中完成整个处理.
首先我们创建了一个Socket用于侦听客户端的连接请求,接下我们创建了一个拥有30个线程的线程池。并在每个线程中实现了Accept、Receive、Send和Close(),以完成连接、接收、发送、关闭的操作。
private Socket listener;
{
// 建立socket偵聽連接
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint locEP = new IPEndPoint(IPAddress.Any, 2000 );
listener.Bind(locEP);
listener.Listen( 100 );
// 建立一個線程池
Thread[] ClientThreadList = new Thread[ 30 ];
for ( int i = 0 ; i <= 30 ; i ++ )
{
ClientThreadList[i] = new Thread( new ThreadStart(ClientWorkThread));
ClientThreadList[i].Start();
}
}
private void ClientWorkThread()
{
byte [] buffer = new byte [ 1024 ];
while ( true )
{
Socket socket = listener.Accept();
// string recString = "接收到来自" + remoEP.Address.ToString() + "的连接。";
// this.Invoke(new AddListItemHandler(this.AddListItem), new string[] { recString });
int receCount = socket.Receive(buffer);
if (receCount > 0 )
{
// string recString = "来自客户端" + remoEP.Address.ToString() + "的消息:" + Encoding.Default.GetString(buffer, 0, receiveCount);
// this.Invoke(new AddListItemHandler(this.AddListItem), new string[] { recString });
socket.Send(buffer, receCount, SocketFlags.None);
}
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
說明:本文是根據下面的鏈接改寫的,可以說是本人的理解思路.算做筆記吧.
參考文獻: 1. http://www.cnblogs.com/wzd24/archive/2007/05/21/753709.html