An Introduction to Socket Programming in .NET(转载)

Introduction

In this article, we will learn the basics of socket programming in .NET Framework using C#. Secondly, we will create a small application consisting of a server and a client, which will communicate using TCP and UDP protocols.
Pre-requisites

    * Must be familiar with .NET Framework.
    * Should have good knowledge of C#.
    * Basic knowledge of socket programming.

1.1 Networking basics:

Inter-Process Communication i.e. the capability of two or more physically connected machines to exchange data, plays a very important role in enterprise software development. TCP/IP is the most common standard adopted for such communication. Under TCP/IP each machine is identified by a unique 4 byte integer referred to as its IP address (usually formatted as 192.168.0.101). For easy remembrance, this IP address is mostly bound to a user-friendly host name. The program below (showip.cs) uses the System.Net.Dns class to display the IP address of the machine whose name is passed in the first command-line argument. In the absence of command-line arguments, it displays the name and IP address of the local machine.

using System;
using System.Net;
class ShowIP{
    public static void Main(string[] args){
        string name = (args.Length < 1) ? Dns.GetHostName() : args[0];
        try{
            IPAddress[] addrs = Dns.Resolve(name).AddressList;
            foreach(IPAddress addr in addrs)
                Console.WriteLine("{0}/{1}",name,addr);
        }catch(Exception e){
            Console.WriteLine(e.Message);
        }
    }
}

Dns.GetHostName() returns the name of the local machine and Dns.Resolve() returns IPHostEntry for a machine with a given name, the AddressList property of which returns the IPAdresses of the machine. The Resolve method will cause an exception if the mentioned host is not found.

Though IPAddress allows to identify machines in the network, each machine may host multiple applications which use network for data exchange. Under TCP/IP, each network oriented application binds itself to a unique 2 byte integer referred to as its port-number which identifies this application on the machine it is executing. The data transfer takes place in the form of byte bundles called IP Packets or Datagrams. The size of each datagram is 64 KByte and it contains the data to be transferred, the actual size of the data, IP addresses and port-numbers of sender and the prospective receiver. Once a datagram is placed on a network by a machine, it will be received physically by all the other machines but will be accepted only by that machine whose IP address matches with the receiver’s IP address in the packet. Later on, this machine will transfer the packet to an application running on it which is bound to the receiver’s port-number present in the packet.

TCP/IP suite actually offers two different protocols for data exchange. The Transmission Control Protocol (TCP) is a reliable connection oriented protocol while the User Datagram Protocol (UDP) is not very reliable (but fast) connectionless protocol.
1.2 Client-Server programming with TCP/IP:

Under TCP there is a clear distinction between the server process and the client process. The server process starts on a well known port (which the clients are aware of) and listens for incoming connection requests. The client process starts on any port and issues a connection request.

The basic steps to create a TCP/IP server are as follows:

   1. Create a System.Net.Sockets.TcpListener with a given local port and start it:

      TcpListener listener = new TcpListener(local_port);
      listener.Start();

   2. Wait for the incoming connection request and accept a System.Net.Sockets.Socket object from the listener whenever the request appears:

      Socket soc = listener.AcceptSocket(); // blocks

   3. Create a System.Net.Sockets.NetworkStream from the above Socket:

      Stream s = new NetworkStream(soc);

   4. Communicate with the client using the predefined protocol (well established rules for data exchange):
   5. Close the Stream:

      s.Close();

   6. Close the Socket:

      s.Close();

   7. Go to Step 2.

Note when one request is accepted through step 2 no other request will be accepted until the code reaches step 7. (Requests will be placed in a queue or backlog.) In order to accept and service more than one client concurrently, steps 2 – 7 must be executed in multiple threads. Program below (emptcpserver.cs) is a multithreaded TCP/IP server which accepts employee name from its client and sends back the job of the employee. The client terminates the session by sending a blank line for the employee’s name. The employee data is retrieved from the application’s configuration file (an XML file in the directory of the application and whose name is the name of the application with a .config extension).
Collapse

using System;
using System.Threading;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Configuration;

class EmployeeTCPServer{
    static TcpListener listener;
    const int LIMIT = 5; //5 concurrent clients
    
    public static void Main(){
        listener = new TcpListener(2055);
        listener.Start();
        #if LOG
            Console.WriteLine("Server mounted,
                            listening to port 2055");
        #endif
        for(int i = 0;i < LIMIT;i++){
            Thread t = new Thread(new ThreadStart(Service));
            t.Start();
        }
    }
    public static void Service(){
        while(true){
            Socket soc = listener.AcceptSocket();
            //soc.SetSocketOption(SocketOptionLevel.Socket,
            //        SocketOptionName.ReceiveTimeout,10000);
            #if LOG
                Console.WriteLine("Connected: {0}",
                                         soc.RemoteEndPoint);
            #endif
            try{
                Stream s = new NetworkStream(soc);
                StreamReader sr = new StreamReader(s);
                StreamWriter sw = new StreamWriter(s);
                sw.AutoFlush = true; // enable automatic flushing
                sw.WriteLine("{0} Employees available",
                      ConfigurationSettings.AppSettings.Count);
                while(true){
                    string name = sr.ReadLine();
                    if(name == "" || name == null) break;
                    string job =
                        ConfigurationSettings.AppSettings[name];
                    if(job == null) job = "No such employee";
                    sw.WriteLine(job);
                }
                s.Close();
            }catch(Exception e){
                #if LOG
                    Console.WriteLine(e.Message);
                #endif
            }
            #if LOG
                Console.WriteLine("Disconnected: {0}",
                                        soc.RemoteEndPoint);
            #endif
            soc.Close();
        }
    }
}

Here is the content of the configuration file (emptcpserver.exe.config) for the above application:

<configuration>
    <appSettings>
        <add key = "john" value="manager"/>
        <add key = "jane" value="steno"/>
        <add key = "jim" value="clerk"/>
        <add key = "jack" value="salesman"/>
    </appSettings>
</configuration>

The code between #if LOG and #endif will be added by the compiler only if the symbol LOG is defined during compilation (conditional compilation). You can compile the above program either by defining the LOG symbol (information is logged on the screen):

    * csc /D:LOG emptcpserver.cs

or without the LOG symbol (silent mode):

    * csc emptcpserver.cs

Mount the server using the command start emptcpserver.

To test the server you can use: telnet localhost 2055.

Or, we can create a client program. Basic steps for creating a TCP/IP client are as follows:

   1. Create a System.Net.Sockets.TcpClient using the server’s host name and port:

      TcpClient client = new TcpClient(host, port);

   2. Obtain the stream from the above TCPClient.

      Stream s = client.GetStream()

   3. Communicate with the server using the predefined protocol.
   4. Close the Stream:

      s.Close();

   5. Close the connection:

      client.Close();

The program below (emptcpclient.cs) communicates with EmployeeTCPServer:
Collapse

using System;
using System.IO;
using System.Net.Sockets;

class EmployeeTCPClient{
    public static void Main(string[] args){
        TcpClient client = new TcpClient(args[0],2055);
        try{
            Stream s = client.GetStream();
            StreamReader sr = new StreamReader(s);
            StreamWriter sw = new StreamWriter(s);
            sw.AutoFlush = true;
            Console.WriteLine(sr.ReadLine());
            while(true){
                Console.Write("Name: ");
                string name = Console.ReadLine();
                sw.WriteLine(name);
                if(name == "") break;
                Console.WriteLine(sr.ReadLine());
            }
            s.Close();
        }finally{
            // code in finally block is guranteed
            // to execute irrespective of
            // whether any exception occurs or does
            // not occur in the try block
            client.Close();
        }
    }
}

1.3 Multicasting with UDP

Unlike TCP, UDP is connectionless i.e. data can be send to multiple receivers using a single socket. Basic UDP operations are as follows:

   1. Create a System.Net.Sockets.UdpClient either using a local port or remote host and remote port:

      UdpClient client = new UdpClient(local_ port);

      or

      UdpClient client = new UdpClient(remote_host, remote_port);

   2. Receive data using the above UdpClient:

      System.Net.IPEndPoint ep = null;
      byte[] data = client.Receive(ref ep);

      byte array data will contain the data that was received and ep will contain the address of the sender.
   3. Send data using the above UdpClient..

      If the remote host name and the port number have already been passed to the UdpClient through its constructor, then send byte array data using:

      client.Send(data, data.Length);

      Otherwise, send byte array data using IPEndPoint ep of the receiver:

      client.Send(data, data.Length, ep);

The program below (empudpserver.cs) receives the name of an employee from a remote client and sends it back the job of that employee using UDP:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Configuration;

class EmployeeUDPServer{
    public static void Main(){
        UdpClient udpc = new UdpClient(2055);
        Console.WriteLine("Server started, servicing on port 2055");
        IPEndPoint ep = null;
        while(true){
            byte[] rdata = udpc.Receive(ref ep);
            string name = Encoding.ASCII.GetString(rdata);
            string job = ConfigurationSettings.AppSettings[name];
            if(job == null) job = "No such employee";
            byte[] sdata = Encoding.ASCII.GetBytes(job);
            udpc.Send(sdata,sdata.Length,ep);
        }
    }
}

Here is the content of the configuration file (empudpserver.exe.config) for above application:

<configuration>
    <appSettings>
        <add key = "john" value="manager"/>
        <add key = "jane" value="steno"/>
        <add key = "jim" value="clerk"/>
        <add key = "jack" value="salesman"/>
    </appSettings>
</configuration>

The next program (empudpclient.cs) is a UDP client to the above server program:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class EmployeeUDPClient{
    public static void Main(string[] args){
        UdpClient udpc = new UdpClient(args[0],2055);
        IPEndPoint ep = null;
        while(true){
            Console.Write("Name: ");
            string name = Console.ReadLine();
            if(name == "") break;
            byte[] sdata = Encoding.ASCII.GetBytes(name);
            udpc.Send(sdata,sdata.Length);
            byte[] rdata = udpc.Receive(ref ep);
            string job = Encoding.ASCII.GetString(rdata);
            Console.WriteLine(job);
        }
    }
}

UDP also supports multicasting i.e. sending a single datagram to multiple receivers. To do so, the sender sends a packet to an IP address in the range 224.0.0.1 – 239.255.255.255 (Class D address group). Multiple receivers can join the group of this address and receive the packet. The program below (stockpricemulticaster.cs) sends a datagram every 5 seconds containing the share price (a randomly calculated value) of an imaginary company to address 230.0.0.1:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class StockPriceMulticaster{
    static string[] symbols = {"ABCD","EFGH", "IJKL", "MNOP"};
    public static void Main(){
        UdpClient publisher = new UdpClient("230.0.0.1",8899);
        Console.WriteLine("Publishing stock prices to 230.0.0.1:8899");
        Random gen = new Random();
        while(true){
            int i = gen.Next(0,symbols.Length);
            double price = 400*gen.NextDouble()+100;
            string msg = String.Format("{0} {1:#.00}",symbols,price);
            byte[] sdata = Encoding.ASCII.GetBytes(msg);
            publisher.Send(sdata,sdata.Length);
            System.Threading.Thread.Sleep(5000);
        }
    }
}

Compile and start stockpricemulticaster.

The next program (stockpricereceiver.cs) joins the group of address 230.0.0.1, receives 10 stock prices and then leaves the group:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class StockPriceReceiver{
    public static void Main(){
        UdpClient subscriber = new UdpClient(8899);
        IPAddress addr = IPAddress.Parse("230.0.0.1");
        subscriber.JoinMulticastGroup(addr);
        IPEndPoint ep = null;
        for(int i=0; i<10;i++){
            byte[] pdata = subscriber.Receive(ref ep);
            string price = Encoding.ASCII.GetString(pdata);
            Console.WriteLine(price);
        }
        subscriber.DropMulticastGroup(addr);
    }
}

Compile and run stockpricereceiver.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据来源:中经数据库 主要指标110多个(全部都是纯粹的 市辖区 指标),大致是: GDP GDP增速 第一产业增加值占GDP比重 第二产业增加值占GDP比重 第三产业增加值占GDP比重 人均GDP 社会消费品零售总额 固定资产投资(不含农户) 新设外商投资企业数_外商直接投资 实际利用外资金额(美元) 一般公共预算收入 一般公共预算支出 一般公共预算支出_教育 一般公共预算支出_科学技术 金融机构人民币各项存款余额_个人储蓄存款 金融机构人民币各项存款余额 金融机构人民币各项贷款余额 规模以上工业企业单位数 规模以上工业企业单位数_内资企业 规模以上工业企业单位数_港澳台商投资企业 规模以上工业企业单位数_外商投资企业 规模以上工业总产值 规模以上工业总产值_内资企业 规模以上工业总产值_港澳台商投资企业 规模以上工业总产值_外商投资企业 规模以上工业企业流动资产合计 规模以上工业企业固定资产合计 规模以上工业企业利润总额 规模以上工业企业应交增值税 规模以上工业企业主营业务税金及附加 户籍人口数 年均户籍人口数 户籍人口自然增长率 第一产业就业人员占全部城镇单位就业人员比重 第二产业就业人员占全部城镇单位就业人员比重 第三产业就业人员占全部城镇单位就业人员比重 城镇非私营单位就业人员数 城镇非私营单位就业人员数_第一产业 城镇非私营单位就业人员数_第二产业 城镇非私营单位就业人员数_第三产业 城镇非私营单位就业人员数_农、林、牧、渔业 城镇非私营单位就业人员数_采矿业 城镇非私营单位就业人员数_制造业 城镇非私营单位就业人员数_电力、热力、燃气及水生产和供应业 城镇非私营单位就业人员数_建筑业 城镇非私营单位就业人员数_批发和零售业 城镇非私营单位就业人员数_交通运输、仓储和邮政业 城镇非私营单位就业人员数_住宿和餐饮业 城镇非私营单位就业人员数_信息传输、软件和信息技术服务业 城镇非私营单位就业人员数_金融业 城镇非私营单位就业人员数_房地产业 城镇非私营单位就业人员数_租赁和商务服务业 城镇非私营单位就业人员数_科学研究和技术服务业 城镇非私营单位就业人员数_水利、环境和公共设施管理业 城镇非私营单位就业人员数_居民服务、修理和其他服务业 城镇非私营单位就业人员数_教育 城镇非私营单位就业人员数_卫生和社会工作 城镇非私营单位就业人员数_文化、体育和娱乐业 城镇非私营单位就业人员数_公共管理、社会保障和社会组织 城镇非私营单位在岗职工平均人数 城镇就业人员数_私营企业和个体 城镇非私营单位在岗职工工资总额 城镇非私营单位在岗职工平均工资 城镇登记失业人员数 建成区面积 建设用地面积 建设用地面积_居住用地 液化石油气供气总量 液化石油气供气总量_居民家庭 人工煤气、天然气供气总量 人工煤气、天然气供气总量_居民家庭 液化石油气用气人口 人工煤气、天然气用气人口 城市公共汽电车运营车辆数 城市出租汽车运营车辆数 城市公共汽电车客运总量 道路面积 排水管道长度 建成区绿化覆盖面积 建成区绿化覆盖率 绿地面积 公园绿地面积 维护建设资金支出 土地面积 生活用水供水量 供水总量 全社会用电量 城乡居民生活用电量 工业生产用电量 房地产开发投资 房地产开发投资_住宅 限额以上批发和零售业法人单位数 限额以上批发和零售业商品销售总额 普通中学学校数 中等职业教育学校数 普通小学学校数 普通高等学校专任教师数 普通中学专任教师数 中等职业教育专任教师数 普通小学专任教师数 普通高等学校在校生数 普通中学在校生数 中等职业教育在校生数 普通小学在校生数 电视节目综合人口覆盖率 公共图书馆总藏量_图书 医疗卫生机构数_医院和卫生院 卫生人员数_执业(助理)医师 医疗卫生机构床位数_医院和卫生院 城镇职工基本养老保险参保人数 职工基本医疗保险参保人数 失业保险参保人数
机器学习是一种人工智能(AI)的子领域,致力于研究如何利用数据和算法让计算机系统具备学习能力,从而能够自动地完成特定任务或者改进自身性能。机器学习的核心思想是让计算机系统通过学习数据中的模式和规律来实现目标,而不需要显式地编程。 机器学习应用非常广泛,包括但不限于以下领域: 图像识别和计算机视觉: 机器学习在图像识别、目标检测、人脸识别、图像分割等方面有着广泛的应用。例如,通过深度学习技术,可以训练神经网络来识别图像中的对象、人脸或者场景,用于智能监控、自动驾驶、医学影像分析等领域。 自然语言处理: 机器学习在自然语言处理领域有着重要的应用,包括文本分类、情感分析、机器翻译、语音识别等。例如,通过深度学习模型,可以训练神经网络来理解和生成自然语言,用于智能客服、智能助手、机器翻译等场景。 推荐系统: 推荐系统利用机器学习算法分析用户的行为和偏好,为用户推荐个性化的产品或服务。例如,电商网站可以利用机器学习算法分析用户的购买历史和浏览行为,向用户推荐感兴趣的商品。 预测和预测分析: 机器学习可以用于预测未来事件的发生概率或者趋势。例如,金融领域可以利用机器学习算法进行股票价格预测、信用评分、欺诈检测等。 医疗诊断和生物信息学: 机器学习在医疗诊断、药物研发、基因组学等领域有着重要的应用。例如,可以利用机器学习算法分析医学影像数据进行疾病诊断,或者利用机器学习算法分析基因数据进行疾病风险预测。 智能交通和物联网: 机器学习可以应用于智能交通系统、智能城市管理和物联网等领域。例如,可以利用机器学习算法分析交通数据优化交通流量,或者利用机器学习算法分析传感器数据监测设备状态。 以上仅是机器学习应用的一部分,随着机器学习技术的不断发展和应用场景的不断拓展,机器学习在各个领域都有着重要的应用价值,并且正在改变我们的生活和工作方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值