• C#网络编程


    Socket编程

    Socket中文译名为套接字,所谓的套接字其实是网络传输中端点的抽象表示。
    那么,端点又是什么呢?它其实就是网络传输中传输的起点或者终点,只是这个起点或者终点比较特殊,它是由两部分组成:ip地址和端口号,用(Ip地址:端口号)的形式表示。套接字是TCP/IP的网络通信的基本操作单元。
    那么,什么又是TCP/IP网络通信呢?这是一个很宽泛的概念,说的直白点,我们现在所用的互联网就是基于这种架构研发的,它是互联网的基础通信架构。涉及的概念也特别多。比如说IP,TCP/UDP协议,ICMP,以及我们更加熟悉的http、ftp,但是在C#网络编程当中,我们最常用的也就是TCP/UDP的概念,了解一下这两个概念,以及相关的编程方法,就可以应对很对网络编程了。

    TCP协议

    参考这个博文
    tcp协议详解

    利用Socket编程,我们可以搭建建议的客户端与服务器端,相关步骤和代码如下所示:
    Socket编程-Tcp服务器端:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;

    namespace Socket_Tcp
    {
    class Program
    {
    static void Main(string[] args)
    {
    //服务器端
    //1.创建socket
    Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    //绑定ip地址和端口号(每个软件都会有一个端口号)
    IPAddress ipAddress = new IPAddress(new byte[] {192,168,101,8 }); //IP地址可以用ipconfig查看一下
    EndPoint endPoint = new IPEndPoint(ipAddress,2333); //IPEndPoint对端口号和ip地址进行了封装,2333是随便写的一个端口号
    tcpServer.Bind(endPoint);

    //开始监听
    tcpServer.Listen(150); //最多允许150的客户端进行连接

    //clientSocket为返回的客户端消息
    Socket clientSocket = tcpServer.Accept();//暂停当前线程,直到有一个客户端连接之后,再执行该行以下的代码
    string message = "我往客户端发消息";
    var bypeMessage = Encoding.UTF8.GetBytes(message); //将Message转换为byte类型
    clientSocket.Send(bypeMessage);

    //接收客户端返回的消息
    byte[] backDate = new byte[1024];//用来接收服务器返回的消息
    int length = clientSocket.Receive(backDate);
    string backMessage = Encoding.UTF8.GetString(backDate, 0, length);
    Console.WriteLine(backMessage);
    Console.ReadKey();
    }
    }
    }

    socket编程-Tcp客户端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;

    namespace Socket_Tcp_Client
    {
    class Program
    {
    static void Main(string[] args)
    {
    //客户端
    //创建Socket
    Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    //发起建立连接的请求
    IPAddress ipAddress = IPAddress.Parse("192.168.101.8");
    EndPoint endPoint = new IPEndPoint(ipAddress, 2333);
    tcpClient.Connect(endPoint); // 客户端不需要监听,但是要和服务器连接,且Ip地址和端口号要和服务器保持一致
    byte[] date = new byte[1024];
    int length = tcpClient.Receive(date); // 用date存储接收过来的数据,长度是length

    string message = Encoding.UTF8.GetString(date, 0, length);//将接收的date转换为string类型
    Console.WriteLine(message);

    //向服务器返回消息
    string backMessage = Console.ReadLine();//返回的消息由用户输入
    tcpClient.Send(Encoding.UTF8.GetBytes(backMessage));//向服务器发送消息

    Console.ReadKey();
    }
    }
    }

    UDP协议

    参考这个博文
    UDP协议学习

    这个博文当中已经说明了这么几种情况:
    1.首先,UDP是无连接协议,所以对比一下TCP协议的编程方式,我们不难发现,UDP当中少了建立连接这个过程。
    2.UDP协议是一种数据报协议,所以不同于TCP协议采用的Stream方式,而是采用Dgram的方式,这个在Socket编程当中也有所体现。

    UDP服务器端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    namespace udp_server
    {
    class Program
    {
    private static Socket udpServer;
    static void Main(string[] args)
    {
    //创建Socket
    udpServer = new Socket(AddressFamily.InterNetwork,
    SocketType.Dgram, ProtocolType.Udp);

    //绑定ip和端口号
    udpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.101.8"),2333));

    //接收数据
    new Thread(ReceiveMessage) { IsBackground = true }.Start();//设置成后台线程,因为程序运行结束,也就不需要这个线程了。


    udpServer.Close();
    Console.ReadKey();
    }

    private static void ReceiveMessage()
    {
    while (true)
    {
    EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
    byte[] data = new byte[1024];
    int length = udpServer.ReceiveFrom(data, ref remoteEndPoint);

    string message = Encoding.UTF8.GetString(data, 0, length);

    Console.WriteLine("从ip: " + (remoteEndPoint as IPEndPoint).Address.ToString()
    + (remoteEndPoint as IPEndPoint).Port + "收到了数据: " + message);
    }
    }
    }
    }

    UDP客户端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22大专栏  C#网络编程pan>
    23
    24
    25
    26
    27
    28
    29
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;

    namespace udp_socket_Client
    {
    class Program
    {
    static void Main(string[] args)
    {
    Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram
    , ProtocolType.Udp);
    //发送数据
    while (true)
    {
    EndPoint serverPoint = new IPEndPoint(IPAddress.Parse("192.168.101.8"), 2333));
    string message = Console.ReadLine();
    byte[] data = Encoding.UTF8.GetBytes(message);
    udpClient.SendTo(data, serverPoint);
    }

    Console.ReadKey();
    }
    }
    }

    监听器

    TCP和UDP编程除了可以使用Socket以外,还可以使用TcpListener和UdpClient,具体编码和步骤如下所示。

    TcpListener

    服务器端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;

    namespace Tcplistener_Server
    {
    class Program
    {
    static void Main(string[] args)
    {
    //1.对socket进行封装,tcpListener内本身包含套接字
    TcpListener listener = new TcpListener(IPAddress.Parse("192.168.101.8"),2223);

    //2.进行监听
    listener.Start();

    //3.等待用户连接
    TcpClient client = listener.AcceptTcpClient();

    //4.获得客户端发送过来的数据
    NetworkStream stream = client.GetStream();

    //5.读取数据
    byte[] data = new byte[1024];
    while (true)
    {
    int length = stream.Read(data, 0, 1024);
    string message = Encoding.UTF8.GetString(data, 0, length);
    Console.WriteLine("Receive Message: " + message);
    }
    stream.Close();
    client.Close();
    listener.Stop();
    }
    }
    }

    客户端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;

    namespace Tcplistener_Cllient
    {
    class Program
    {
    static void Main(string[] args)
    {
    //1.创建TCP对象的时候,就会与服务器建立联系
    TcpClient client = new TcpClient("192.168.101.8", 2223);

    //2.通过网络流获取数据信息
    NetworkStream stream = client.GetStream();

    while (true)
    {
    //手动输入需要发送的信息
    string message = Console.ReadLine();
    byte[] data = Encoding.UTF8.GetBytes(message);

    //将信息写入网络流
    stream.Write(data, 0, data.Length);
    }

    //关闭流
    stream.Close();
    client.Close();
    Console.ReadKey();
    }
    }
    }

    UdpClient

    消息接收方

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;

    namespace _UdpListener
    {
    class Program
    {
    static void Main(string[] args)
    {
    UdpClient udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse("192.168.101.8"),2223));

    //接收数据
    IPEndPoint point = new IPEndPoint(IPAddress.Any, 0);
    byte[] data = udpClient.Receive(ref point);//通过point确定数据来自哪个ip和端口号,并返回接收的数据
    string message = Encoding.UTF8.GetString(data);
    Console.WriteLine("收到数据: " + message);
    udpClient.Close();
    Console.ReadKey();
    }
    }
    }

    消息发送方

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;

    namespace _udpListenerClient
    {
    class Program
    {
    static void Main(string[] args)
    {
    UdpClient client = new UdpClient();
    string message = Console.ReadLine();
    byte[] data = Encoding.UTF8.GetBytes(message);

    client.Send(data, data.Length, new IPEndPoint(IPAddress.Parse("192.169.101.8"), 2333));
    client.Close();
    Console.ReadKey();
    }
    }
    }

    TCP和UDP的区别

    在看过TCP和UDP的相关资料,以及编写相关代码之后,我们不难总结出这两个协议的这几个不同之处:

    连接方式

    TCP需要客户端与服务器之间的连接操作,连接的时候需要“三次握手”,断开连接则需要“四次挥手”,而UDP协议则没有这个过程。

    复杂程度

    TCP协议相对复杂,这当中包含了容错机制,以及拥堵的处理等,正式因为如此,TCP的可靠性较高。而UDP则要简单许多,相对的,UDP的可靠性也比较低下。

    传输模式

    TCP的传输,使用的是流模式(Stream),而UDP则采用的是数据报。

  • 相关阅读:
    Map集合
    MySql函数之CONCAT、CONCAT_WS、GROUP_CONCAT函数详解
    mysql字符串转数字排序
    阿里巴巴Json工具Fastjson教程
    tf.set_shape
    numpy切片X[:,0]和X[:,1]
    numpy索引和切片 np.newaxis np.arange
    tf.cast()用于张量数据类型的转换
    自监督
    在神经网络中bias偏置有什么作用?
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12026648.html
Copyright © 2020-2023  润新知