初学网络通信编程时应该注意的常见问题

首先让我们写一个C/S多线程网络程序,通过这个程序了解初学网络编程是应该注意的几个问题。

下面开始设计服务器端的业务逻辑代码:

首先,值得强调的是,要在该文件的顶端添加多线程和网络的命名空间语句:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
//可以套接字
using System.Net.Sockets;
//可以使用多线程
using System.Threading;
 
接写来,设计类Threadtcpserver。代码如下:
 class Threadtcpserver
    {
        private Socket server;
        public Threadtcpserver()
        {
            //初始化IP地址
            IPAddress local = IPAddress.Parse("127.0.0.1");
            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();
            }
        }
    
    }

1.创建套接字Server,并将其与本地这结点iep进行绑定。然后,在13000端口上监听是否有新的客户端进行连接。

2.在无限循环中有一个阻塞的方法Accept(),该方法直到有新客户端连接到服务器上时,把客户端的套接字信息传递给client对象。否则,将阻塞直到有客户机进行连接。

3.ClientThread类负责处理客户端与服务器之间的通信。先把客户端的套接字句柄传递给负责消息服务的ClientThread类。然后,把ClientThread类的ClientService方法委托给线程,并启动线程。

 

然后开始编写ClientThread类的代码:

class ClientThread
    {
        //connection变量表示连接数
        public static int connection = 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)
            {
                connection++;
            }
            Console.WriteLine("新客户建立连接:{0}个连接数", connection);
            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();
            connection--;
            Console.WriteLine("客户关闭连接:{0}个连接数", connection);
        }

这段代码的业务逻辑:

1.在构造函数中得到接收到的客户端套接字client,以后就通过service句柄处理消息的接收和发送。

2.ClientService方法是委托给线程的,此方法进行消息的处理工作。在这里实现的功能是,先从客户端接收一条消息,然后把这条消息转换为大写字母,并立即发送一条应答的消息,也就是所谓的echo技术,通常用来进行消息之间的测试。

3.通过connections变量来记录活动连接数。当有新增连接或有断开连接的情况发生时,都会体现connection是的变化。

 

主函数代码如下:


 static void Main(string[] args)
        {
            Threadtcpserver instance = new Threadtcpserver();
        }

Main函数十分简单,生成一个Threadtcpsever实例,然后构造函数就会一步一步地展开,开始执行具体的业务逻辑。

 

编写完服务器端的程序后,只要再配置一个客户端程序即可。下面编写客户端代码:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket client;
            byte[] buf = new byte[1024];
            string input;
            IPAddress local = IPAddress.Parse("127.0.0.1");
            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();
        }
    }
}

客户端是比较简单的,只有一个Main()函数。下面来分析一下这段代码的功能:

1.创建套接字,并通过connect方法连接到本地终结点。当连接建立以后,便可以与服务器进行通信了。

2.在客户端上等待用户输入一条信息,该消息会发送到服务器创建的消息服务线程上的ClientService方法进行处理。


你可能感兴趣的:(多线程,编程,网络,socket,服务器,byte)