利用线程池实现多客户端和单服务器端Socket通讯(一):同步方式

线程池:
线程池使用方式:ThreadPool.QueueUserWorkItem(WaitCallback callBack, object state)
WaitCallback的方法签名:public delegate void WaitCallback(object state) ; //传入一个object上下文

Socket:
常用实例方法:Connect(), Bind(EndPoint localEP), Listen(int backlog), Accept(), Receive(byte[] buffer), Close()

示例:
// Server端

namespace  SocketMultiThreadServer
{
    
public   partial   class  Form1 : Form
    {
        Socket socket;
        
public  Form1()
        {
            InitializeComponent();
            InitSocket();
        }

        
private   void  InitSocket()
        {
            socket 
=   new  Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPHostEntry ipHostEntry 
=  Dns.GetHostEntry(Dns.GetHostName());
            IPEndPoint ipEndPoint 
=   new  IPEndPoint(ipHostEntry.AddressList[ 0 ],  8091 );  //  这个AddressList属性返回的是一个IP列表,包括若干个IPv6、IPv4的值,我们要获取的IPv4值的下标会随着环境的变化改变,不知道有没有解决方法
            socket.Bind(ipEndPoint);
            socket.Listen(
20 );  //  设置允许的挂起连接队列的长度最大值为20
        }

        
private   void  btnBeginRec_Click( object  sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem((_) 
=>
            {
                
while  ( true )
                {
                    Socket socketAccept 
=   null ;
                    
if  (socket.Poll( - 1 , SelectMode.SelectRead))  //  确定socket的状态
                    {
                        socketAccept 
=  socket.Accept();  //  接收客户端发来的Socket连接,每个连接的客户端都会保持一个Socket实例
                    }
                    
if  (socketAccept  !=   null )
                    {
                        ThreadPool.QueueUserWorkItem((o) 
=>
                        {
                            
while  ( true )
                            {
                                
byte [] byteArray  =   new   byte [ 100 ];
                                socketAccept.Receive(byteArray); 
//  接收客户端发来的消息
                                 string  strRec  =  System.Text.Encoding.UTF8.GetString(byteArray);
                                
if  ( this .txtMsg.InvokeRequired)  //  判断当前线程(调用方)是否是主线程之外的线程,txtMsg是一个TextBox
                                {
                                    
this .txtMsg.Invoke( new  ChangeText(ShowMsg), strRec);  //  返回给主线程去做UI呈现
                                }
                                System.Threading.Thread.Sleep(
100 );
                            }
                        });
                    }
                }
            });
            System.Threading.Thread.Sleep(
100 );
        }

        
delegate   void  ChangeText( string  obj);
        
private   void  ShowMsg( string  obj)
        {
            
this .txtMsg.AppendText(obj  +   "    " );
        }
    }
}



// Client端

 

namespace  SocketMultiThreadClient
{
    
class  Program
    {
        
static   void  Main( string [] args)
        {
            Socket socket 
=   new  Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPHostEntry ipHostEntry 
=  Dns.GetHostEntry(Dns.GetHostName());
            IPEndPoint ipEndPoint 
=   new  IPEndPoint(ipHostEntry.AddressList[ 0 ],  8091 );  // 指定要连接的服务端的IP和端口
            socket.Connect(ipEndPoint);

            
while  ( true )
            {
                
string  input  =  Console.ReadLine();
                
try
                {
                    socket.Send(System.Text.Encoding.UTF8.GetBytes(input)); 
//  向服务端(指定的IP和端口)发送流消息
                }
                
catch  (Exception ex)
                {
                    
if  (socket  !=   null )
                    {
                        socket.Close();
                        Console.WriteLine(
" Client Error:  "   +  ex.Message);
                    }
                }
                System.Threading.Thread.Sleep(
100 );
            }
        }
    }
}


Hope this helps. :)

 

利用线程池实现多客户端和单服务器端Socket通讯(二):异步编程模型实现

你可能感兴趣的:(socket)