• 客户端和服务端之间的通信(TCP)


    和上篇的 客户端和服务端之间的通信(UDP)程序类似:http://www.cnblogs.com/Shang0109/archive/2012/07/29/2614176.html

         Socket最初应用于Unix当中,代表了一种文件描述符(在Unix中一切都是以文件为单位的)。在Windows当中则用于描述网路的访问,程序员通过Socket来发送和接收网路中的信息,因此我们可以把它理解为是一个跟网卡交互的API接口函数。

    Socket访问网络的要素:

         1、本机的IP和Port端口(Socket只有与某一个IP和Port绑定,才能偶发挥强大的作用)

         2、必须指定通讯协议如:TCP和UDP。

    在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务

    通过一个简单的实例来了解一下Socket在TCP协议下的基本通讯。

    在程序当中使用到Socket时,需要首先添加“using System.Net; 和using System.Net.Sockets;” 两个引用

    一、新建一个控制台应用程序:Server;

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    
    namespace Server
    {
        class Program
        {
            //1、要使用 Socket 发送和接收数据,必须首先使用 AddressFamily、SocketType 及 ProtocolType 创建它
            //2、SocketType 有时会隐式指示在 AddressFamily 中使用哪个 ProtocolType。例如,当 SocketType 为 Dgram 时,ProtocolType 始终为 Udp。
            //   当 SocketType 为 Stream 时,ProtocolType 始终为 Tcp。如果试图使用不兼容的组合创建 Socket,则 Socket 将引发 SocketException。
    
            static void Main(string[] args)
            {
                //第一步,定义一个Socket套接字
                Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //SocketType.Stream支持可靠、双向、基于连接的字节流,而不重复数据,也不保留边界。此类型的 Socket 与单个对方主机进行通信,并且在通信开始之前需要远程主机连接。Stream 使用传输控制协议 (Tcp) ProtocolType 和 InterNetworkAddressFamily。
                //AddressFamily.InterNetwork表示使用的IP地址是4段的,
                
                //第二步,绑定ip和端口
                IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
                s.Bind(ipep);
                
                //第三步,通知TCP,服务器已经就绪
                s.Listen(0);//TCP是面向连接的,需要用Listen()方法监听一下网络上是否有人发送东西过来。
                //而UDP则不需要,UDP是无连接的,来者不拒。
                Console.WriteLine("服务器已启动!");
    
                //第四步,等待客户端的连接请求
                Socket client = s.Accept();
                //TCP情况下,如果监听到一个连接,就可以使用Accept()方法进行接收这个连接,然后执行Send()或者Receive()
                //UDP则不需要Accept(),直接用SendTo/ReceiveFrom来执行操作。
                //UDP不建立连接,所以发送前并不知道对方的IP和端口,因此需要指定一个发送的节点才能进行正常的发送和接收。(参照上篇UDP:http://www.cnblogs.com/Shang0109/archive/2012/07/29/2614176.html
                Console.WriteLine("有客户端:" + client.RemoteEndPoint.ToString() + "连接");
                
                byte[] recv = new byte[1024]; //定义一个byte类型的数组用于接收信息
                //接收客户端的信息,并保存到byte数组中(Receive()使用指定的 SocketFlags,从绑定的 Socket 接收数据,将数据存入接收缓冲区。)
                //SocketFlags:指定套接字的发送和接收行为。None:不对此调用使用标志。
                int bytes = client.Receive(recv, recv.Length, SocketFlags.None);
                //将byte数组转换成可读的string
                string receive = Encoding.ASCII.GetString(recv, 0, bytes);//进接收的信息转换成相应的字符串
                Console.WriteLine("接收到一条信息:" + receive);
    
                string sendString = "hello,this is a string from server";
                byte[] send = Encoding.ASCII.GetBytes(sendString);
                client.Send(send, send.Length, SocketFlags.None);
    
                client.Close();
                s.Close();//关闭套接字,服务停止
                Console.ReadLine();
            }
        }
    }

    二、新建一个控制台应用程序:Client;

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    
    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
                //客户端和服务端类似
                //第一步:建立套接字
                Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                
                //第二步:将套接字于远程主机连接
                IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);//127.0.0.1指定本机的IP地址
                s.Connect(ipep);//连接服务器
    
                //第三步:发送信息
                string sendString = "this is a string to send";
                byte[] send = Encoding.ASCII.GetBytes(sendString);//将发送的信息转换成byte类型数组
                s.Send(send, send.Length, SocketFlags.None);
    
                byte[] recv = new byte[1024];
                int length = s.Receive(recv, recv.Length, SocketFlags.None);
                string receive = Encoding.ASCII.GetString(recv, 0, length);
                Console.WriteLine("从服务器端接收到一条信息:" + receive);
    
                s.Close();
                Console.ReadLine();
            }
        }
    }

    三、运行:先启动服务器,之后运行客户端程序。

  • 相关阅读:
    python基础学习(2)
    python基础语法
    面试常见问题(2)——数据库
    面试常见问题(1)——TCP协议
    python基础回顾(一)
    安装Beautiful Soup
    MongoDB的安装、配置和可视化
    神奇的斐波那契---解决兔子繁衍问题
    正规式、正规文法与自动机
    词法分析程序的设计与实现
  • 原文地址:https://www.cnblogs.com/Shang0109/p/2620465.html
Copyright © 2020-2023  润新知