C#网络编程之多线程socket实例

服务器端:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Net;  
using System.Net.Sockets;  
using System.Threading;  

namespace multithreadservTest  
{  
    class Threadtcpserver  
    {  

        /* 本程序中采用了多线程技术,可以应付多客户的需求。首先,程序的主线程也就是程序的入口即Main()函数, * 当执行到Accept方法时,线程变会阻塞;当有新连接时,就创建相应的消息服务线程。而主程序则继续进行监听, * 检查有没有新的连接进入。如果客户端有向服务器连接的请求,那么就把连接句柄传递给接收的套接字。由于线程 * 的调度和切换是非常快的,快得足以让我们分辨不出程序的运行顺序,所以从宏观上来讲,可以说程序是并行执行 * 的。但事实上,从微观的角度上说,只是cpu飞快地调度线程,让我们感觉好像可以同时接收连接和处理消息一样, * 但在一个时刻,只有一个线程是处于运行状态的。 */  


        /// <summary> 
        /// 下面这段代码的业务逻辑是: 
        /// (1)创建套接字server,并将其与本地终结点iep进行绑定。然后,在13000端口上监听是否 
                  有新的客户端进行连接  
        /// (2)在无限循环中有一个阻塞的方法Accept,该方法直到有新客户端连接到服务器上时,把 
                  客户端的套接字信息传递给client对象。否则,将阻塞 直到有客户机进行连接。  
        /// (3)ClientThread类负责客户端与服务器端之间的通信。先把客户端的套接字句柄传递给 
        /// 负责消息服务的ClientThread类。然后,把ClientThread类 的ClientService方 
                  法委托给线程,并启动线程。   
        /// </summary> 
        private Socket server;  
        public Threadtcpserver()  
        {  
            //初始化IP地址 
            IPAddress local=IPAddress.Parse("192.168.5.187");  
            IPEndPoint iep = new IPEndPoint(local, 13000);  
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream,  
            ProtocolType.Tcp);  
            //将套接字与本地终结点绑定 
            server.Bind(iep);  
            //在本地13000端口号上进行监听 
            server.Listen(20);  
            Console.WriteLine("等待客户机进行连接......");  
            while (true)  
            {  
                //得到包含客户端信息的套接字 
                Socket client = server.Accept();  
                //创建消息服务线程对象 
                ClientThread newclient = new ClientThread(client);  
                //把ClientThread类的ClientService方法委托给线程 
                Thread newthread = new Thread(new ThreadStart(newclient.ClientService));  
                //启动消息服务线程 
                newthread.Start();  

            }  


        }  


        /// <summary> 
        /// (1)在构造函数中得到接收到的客户套接字client,以后就通过service句柄处理消息的接收 
         /// 和发送。 
        /// (2)ClientService方法是委托给线程的,此方法进行消息的处理工作。在这里实现的功能是, 
        /// 先从客户端接收一条消息,然后把这条消息转换为大写字母,并立即发送一条应答的消息, 
        /// 也就是所谓的echo技术,通常用来进行消息之间的传递。 
        /// (3)还有就是通过connections变量来记录活动的连接数。当有新增连接或断开连接的情况发 
        /// 生时,都会体现出connections的变化。 
       /// </summary> 
        public class ClientThread  
        {  
            //connections变量表示连接数 
            public static int connections = 0;  
            public Socket service;  
            int i;  
            //构造函数 
            public ClientThread(Socket clientsocket)  
            {  
                //service对象接管对消息的控制 
                this.service = clientsocket;  
            }  
            public void ClientService()  
            {  
                String data = null;  
                byte[] bytes = new byte[1024];  
                //如果Socket不是空,则连接数加1 
                if (service != null)  
                {  
                    connections++;  
                }  
                Console.WriteLine("新客户连接建立:{0}个连接数", connections);  
                while((i=service.Receive(bytes))!=0)  
                {  
                    data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);  
                    Console.WriteLine("收到的数据:{0}", data);  
                    //处理客户端发来的消息,这是转化为大写字母 
                    data = data.ToUpper();  
                    byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);  
                    //发送一条应答消息 
                    service.Send(msg);  
                    Console.WriteLine("发送的数据:{0}", data);  
                }  
                //关闭套接字 
                service.Close();  
                connections--;  
                Console.WriteLine("客户关闭连接:{0}个连接数", connections);  
            }  


            /// <summary> 
            /// Main函数十分简单,生成和一个Threadtcpserver实例,然后构造函数就会一步一步地 
              /// 展开,开始执行具体的业务逻辑。 
            /// </summary> 
            /// <param name="args"></param> 
            static void Main(string[] args)  
            {  
                Threadtcpserver instance = new Threadtcpserver();  
            }  


        }  

    }  
}  

客户端:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Net;  
using System.Net.Sockets;  


namespace multithreadclientTest  
{  
    class Program  
    {  
        /// <summary> 
        /// 本程序代码的主要功能: 
        /// (1)创建套接字,并通过connect方法连接到本地终结点。当连接建立以后,便可以与服务器进 
        /// 行通讯了。 
        /// (2)在客户端上等待用户输入一条消息,该消息会发送到服务器创建的消息服务线程上 
        /// 的ClientService 方法上进行处理。在将该消息转化为大写字母后,发还给客户端。 
        /// 这是一个echo技术。如果在控制台上输入exit 接断开与服务器之间的连接。 
        /// </summary> 
        /// <param name="args"></param> 
        static void Main(string[] args)  
        {  
            Socket client;  
            byte[] buf = new byte[1024];  
            string input;  
            IPAddress local = IPAddress.Parse("192.168.5.187");  
            IPEndPoint iep = new IPEndPoint(local, 13000);  

            try  
            {  
                client = new Socket(AddressFamily.InterNetwork, SocketType.Stream,  
                ProtocolType.Tcp);  
                client.Connect(iep);  
            }  
            catch (SocketException)  
            {  
                Console.WriteLine("无法连接到服务器!");  
                return;  
            }  
            finally  
            {  

            }  
            while (true)  
            {  
                //在控制台上输入一条消息 
                input = Console.ReadLine();  
                //输入exit,可以断开与服务器的连接 
                if (input == "exit")  
                {  
                    break;  
                }  
                client.Send(Encoding.ASCII.GetBytes(input));  
                //得到实际收到的字节总数 
                int rec = client.Receive(buf);  
                Console.WriteLine(Encoding.ASCII.GetString(buf, 0, rec));  

            }  
            Console.WriteLine("断开与服务器的连接......");  
            client.Close();  


        }  
    }  
}  

你可能感兴趣的:(C#网络编程之多线程socket实例)