Socket編程--同步的應用

同步編程使用的情況不多,在以下3種情況下可以使用同步:
        1.客戶端數量較少情況下的服務端編程
        2.客戶端數量較多,但都是短連接情況下的服務端編程
        3.客戶端編程

以下主要針對服務端編程的2種情況,分別做一示例,以下示例均使用tcp協議.

1.在客戶端數量較少的情況下,

数量较少是指会同时连接到服务器的客户端数量一般在50人以下。这种情况下我们可以考虑使用同步Socket+Thread来实现我们的服务端。这样会让我们编写逻辑更清晰的代码而性能不会下降太多。

首先创建一个Socket,并且给它绑定一个EndPoint后开始监听。接下来我们创建一个线程,在这个线程中我们用一个无限循环来接收来自客户端的连接请求。在接收到一个请求后,为这个客户端创建一个新的线程,并且在这个线程中也使用一个无限循环接收来自这个客户端的数据

private Socket listener;

         private   void  button1_Click( object  sender, EventArgs e)
        {
            
// 建立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;

         private   void  button1_Click( object  sender, EventArgs e)
        {
            
// 建立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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值