zoukankan      html  css  js  c++  java
  • c# Socket通信基础

     一、IP地址操作类      

    1IPAddress      

    a、在该类中有一个 Parse()方法,可以把点分的十进制IP表示转化成IPAddress类,方法如下:     

         IPAddress address = IPAddress.Parse(“192.168.0.1”);

    bIPAddress提供4个只读字段      

          Any   用于代表本地系统可用的任何IP地址 

          Broadcase 用于代表本地网络的IP广播地址 

          Loopback 用于代表系统的回送地址          

          None 用于代表系统上没有网络接口

          其中IPAddress.Any最常用可以用来表示本机上所有的IP地址,这对于socket服务进行侦听时,最方便使用,不用对每个IP进行侦听了。

    IPAddress.Broadcase可用来UDPIP广播,这些具体讲socket时再详细介绍。     

     

    2IPEndPoint                  

       我们可以通过二种构造方法来创建IPEndPoint类:    

    aIPEndPoint(long address, int port)      

    bIPEndPoint(IPAddress address, int port)

     

    四个属性:    

    Address 

    AddressFamily 

    Port 

    MaxPort 

    MinPort 

     

          这些应该从名字上就很好理解,不再一一介绍。IPEndPoint其实就是一个IP地址和端口的绑定,可以代表一个服务,用来Socket通讯。

     

     二、DNS相关类      

    DNS类有四个静态方法,来获取主机DNS相关信息,      

    1GetHostName()       

       通过Dns.GetHostName()可以获得本地计算机的主机名         

    2GetHostByName()      

       根据主机名称,返回一个IPHostEntry 对象:        

         IPHostEntry GetHostByName(string hostName) 

          其中IPHostEntry把一个DNS主机名与一个别名和IP地址的数组相关联,包含三个属性: 

          AddressList:一个IPAddress对象的数组 

     

          Aliases:一个字符串对象数组 

     

          HostName:一个用于主机名的字符串对象      3GetHostByAddress()      类似于GetHostByName(),只不过这里的参数是IP地址,而不是主机名,也返回一个IPHostEntry对象。

          IPHostEntry GetHostByAddress(IPAddress address) 

     

          IPHostEntry GetHostByAddress(string address) 

     

          4Resolve() 

     

          当我们不知道输入的远程主机的地址是哪种格式时(主机名或IP地址),用以上的二种方法来实现,我们可能还要通过判断客户输入的格式,才能正确使用,但Dns类提供一更简单的方法Resolve(),该方法可以接受或者是主机名格式或者是IP地址格式的任何一种地址,并返回IPHostEntry对象。      常用方法就写到这里了,当然针对网络编程不可能只有这么几个类和方法,只不过这几个我们最常用,也非常的简单。

     

       在上一篇中,我列了一些常用的方法,可以说这些方法是一些辅助性的方法,对于分析网络中的主机属性非常有用。在这篇中,我将会介绍一下面向连接(TCPsocket编程,其中辅以实例,代码可供下载。

     

    对于TCPSocket编程,主要分二部分:      

    一、服务端Socket侦听:      服务端Socket侦听主要分以下几个步骤,按照以下几个步骤我们可以很方便的建立起一个Socket侦听服务,来侦听尝试连接到该服务器的客户Socket,从而建立起连接进行相关通讯。    

     

      1、创建IPEndPoint实例,用于Socket侦听时绑定

     

    IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 6001);

     

    2、创建套接字实例

    serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    这里创建的时候用ProtocolType.Tcp,表示建立一个面向连接(TCP)Socket

     3、将所创建的套接字与IPEndPoint绑定

    serverSocket.Bind(ipep);

     

     4、设置套接字为收听模式

    serverSocket.Listen(10);

     以上这四步,我们已经建立了Socket的侦听模式,下面我们就来设置怎么样来获取客户Socket连接的实例,以及连接后的信息发送。      

     

    5、在套接字上接收接入的连接

     

    while (true)            
    {                 
        try               
        {                    
            //在套接字上接收接入的接 6            
            clientSocket = serverSocket.Accept();                     
            clientThread new Thread(new ThreadStart(ReceiveData)); 
            clientThread.Start();                 
         }                
         catch (Exception ex)
         {                   
             MessageBox.Show("listening Error: " + ex.Message);
         }           
    }

     

    通过serverSocket.Accept()来接收客户Socket的连接请求,在这里用循环可以实现该线程实时侦听,而不是只侦听一次。当程序运行serverSocket.Accept()时,会等待,直到有客户端Socket发起连接请求时,获取该客户Socket,如上面的clientSocket。在这里我用多线程来实现与多个客户端Socket的连接和通信,一旦接收到一个连接后,就新建一个线程,执行ReceiveData功能来实现信息的发送和接收。

    6 在套接字上接收客户端发送的信息和发送信息

    private void ReceiveData()
            {
                bool keepalive = true;
                Socket s = clientSocket;
                Byte[] buffer = new Byte[1024];
                //根据收听到的客户端套接字向客户端发送信息 
                IPEndPoint clientep = (IPEndPoint)s.RemoteEndPoint;
                lstServer.Items.Add("Client:" + clientep.Address + "(" + clientep.Port + ")");
                string welcome = "Welcome to my test sever ";
                byte[] data = new byte[1024];
                data = Encoding.ASCII.GetBytes(welcome);
                s.Send(data, data.Length, SocketFlags.None);
                while (keepalive)
                {
                    //在套接字上接收客户端发送的信息
                    int bufLen = 0;
                    try
                    {
                        bufLen = s.Available;
                        s.Receive(buffer, 0, bufLen, SocketFlags.None);
                        if (bufLen == 0)
                            continue;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Receive Error:" + ex.Message);
                        return;
                    }
                    clientep = (IPEndPoint)s.RemoteEndPoint;
                    string clientcommand = System.Text.Encoding.ASCII.GetString(buffer).Substring(0, bufLen);
                    lstServer.Items.Add(clientcommand + "(" + clientep.Address + ":" + clientep.Port + ")");
                }
            }

    通过IPEndPoint clientep = (IPEndPoint)s.RemoteEndPoint;我们可以获取连接上的远程主机的端口和IP地址,如果想查询该主机的其它属性如主机名等,可用于上一篇讲的Dns.GetHostByAddress(string ipAddress)来返回一个IPHostEntry对象,就可以得到。另外我们要注意的是,通过Socket发送信息,必须要先把发送的信息转化成二进字进行传输,收到信息后也要把收到的二进字信息转化成字符形式,这里可以通过Encoding.ASCII.GetBytes(welcome);Encoding.ASCII.GetString(buffer).Substring(0, bufLen);来实现。

          以上就是服务端Socket侦听模式的实现,只要有远程客户端Socket连接上后,就可以轻松的发送信息和接收信息了。下面我们来看看客户端Socket是怎么连接上服务器的。

    二、客户端连接

     

    客户端Socket连接相对来说比较简单了,另外说明一下,在执行客户端连接前,服务端Socket侦听必须先启动,不然会提示服务器拒绝连接的信息。

     

    1、创建IPEndPoint实例和套接字

     IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6001);3            
    clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

     这个跟服务端Socket侦听差不多,下面一步由服务端Socket的侦听模式变成连接模式。

     

     2、将套接字连接到远程服务器

    try 
    { 
         clientSocket.Connect(ipep); 
    } 
    catch (SocketException ex)
    {
        MessageBox.Show("connect error: " + ex.Message);
        return;
    }

     前面已说明,如果在执行Socket连接时,服务器的Socket侦听没有开启的话,会产生一个SocketException异常,如果没有异常发生,那恭喜你,你已经与服务器连接上了,接下来就可以跟服务器通信了。

     

    3、接收信息

    while (true) 
    {
        //接收服务器信息 
       int bufLen = 0;
    try
    { 
        bufLen = clientSocket.Available;
        clientSocket.Receive(data, 0, bufLen, SocketFlags.None);
       if (bufLen == 0)
       {
           continue;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Receive Error:" + ex.Message);
        return;
    }
        string clientcommand = System.Text.Encoding.ASCII.GetString    (data).Substring(0, bufLen);
        lstClient.Items.Add(clientcommand);
    }

     

    4、发送信息

    byte[] data = new byte[1024];
    data = Encoding.ASCII.GetBytes(txtClient.Text);
    clientSocket.Send(data, data.Length, SocketFlags.None);

     客户端的发送信息和接收信息跟服务器的接收发送是一样的,只不过一个是侦听模式而另一个是连接模式。

     

     

     

  • 相关阅读:
    windows系统切换jdk,修改java_home无效情况
    Cannot instantiate interface org.springframework.context.ApplicationListener
    MySQL分组查询获取每个学生前n条分数记录(分组查询前n条记录)
    ASP.NET Web API 使用Swagger生成在线帮助测试文档,支持多个GET
    EF TO MYSQL 无法查询中文的解决方法
    HttpWebRequest post请求获取webservice void数据信息
    This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms. 此实现不是 Windows 平台 FIPS 验证的加密算法的一部分 解决方案
    MySQL 5.7.13解压版安装记录 mysql无法启动教程
    C# udpclient 发送数据断网后自动连接的方法
    汽车XX网站秒杀抢购代码
  • 原文地址:https://www.cnblogs.com/lihaibo-Leao/p/3272421.html
Copyright © 2011-2022 走看看