zoukankan      html  css  js  c++  java
  • 4.socket(-)之控制台

    一Socket介绍:

      网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

      建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。

      Socket在英文原意椒"孔"或者"插座",作为BSD UNIX ,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。

    ------来自百度百科

    --------说一个简单的例子

      大学里男生要去找自己的女朋友,但是女朋友在宿舍,他又没有手机,因为是女生宿舍男生又不能直接去找女生。他只能通过宿舍阿姨去联系女生。这个阿姨就是Socket。男生女生通过阿姨进行通信。在或者我们打电话和别人联系。手机也是。

    在来看看我代码里的Socket 做了哪些处理。

    鄙人不才,画了这个么一个图。

    大致意思就是客户端有一个Socket对象,向服务端发送请求。服务端有一个专门负责监听的Socket,监听的Socket监听到了有请求的时候就会为这个请求创建一个与之对应通信的Socket进行通信。

    接下来讲讲Socket类

    public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);

    首先看看Socket类的构造函数的三个参数。

    AddressFamily 这个参数制定了寻找地址的方案。Socket通过他确定如果解析地址,比如地址设置了IPv4,Socket就会通过Ipv4的规则去解析地址,如果是IPV6就会通过Ipv6规则去解析地址。
    AddressFamily 这个枚举的具体有哪些值可以看MSDN。这里附上传送门----->点击这里

    SocketType    这个参数看名字就是知道干啥用了。Socke Type 就是设置Socket类型,这个参数是与最后一个参数有关联。这里附上传送门------->点击这里

    protocolType 这个参数设置Socket之间的通信协议,就是通信规则,就是类似抗战时期地下工作都有暗号一样。天王盖地虎,宝塔侦镇河妖,只有口号对上了才是自己人,他们都有自己的规则。
             Socket也一样,也需要规定一种口号,一种协议。常见有TCP协议,和UDP协议。这里附上传送门------->点击这里

     


     
    注意:SocketType 有时会隐式指示在 AddressFamily 中使用哪个 ProtocolType。例如,当 SocketType 为 Dgram 时,ProtocolType 始终为 Udp。当 SocketType 为 Stream 时,ProtocolType 始终为 Tcp。如果试图使用不兼容的组合创建 Socket,则 Socket 将引发 SocketException

     

    下面开始掏出一手代码进行说明了

    服务端代码

    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 SocketTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = IPAddress.Any;
                IPEndPoint point = new IPEndPoint(ip, 255);//设置Socket服务端接受请求的Ip和服务端的端口号
                socketWatch.Bind(point);//进行绑定
                Console.WriteLine("正在监听中。。。。。");
                Thread therad = new Thread(listen);
                socketWatch.Listen(10);
                therad.Start(socketWatch);
    
            }
            static void listen(object obj)
            {
                Socket socket = obj as Socket;
                while (true)
                {
                    //等待请求返回,并且创建一个与客户端通信的请求(如果这句话写在主线程里,而且没有请求过来,主线程会卡死,因为它会一直等待)
                    Socket socketsend = socket.Accept();
    
                    //socketsend.RemoteEndPoint 或者请求的Ip地址
                    Console.WriteLine(socketsend.RemoteEndPoint.ToString() + "已经连接上来啦");
                    byte[] byte0 = new byte[1024 * 102];
                    int count = socketsend.Receive(byte0);
                    string str = Encoding.UTF8.GetString(byte0);
                    Console.WriteLine("收到客户端"+ socketsend.RemoteEndPoint.ToString()+"发来的小时:"+str);
    
                    //测试用For循环发三次消息给已经连接的客户端
                    for (int i = 0; i < 3; i++)
                    {
                        string sMsg = "我是服务端,你已经连接上来了,重要的事情说三遍";
                        byte[] bytes = Encoding.UTF8.GetBytes(sMsg);
                        socketsend.Send(bytes); //Send方法是发送消息
                        Thread.Sleep(1000);
                    }
    
                }
            }
        }
    }

    客户端代码

    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 SocketClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                Socket socketclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
                //设置连接服务端的Ip
                IPAddress address = IPAddress.Parse("127.0.0.1");
    
                //设置连接服务端的端口
                IPEndPoint point = new IPEndPoint(address, 255);
    
                //连接
                socketclient.Connect(point);
                byte[] arrRecvmsg = new byte[1024 * 1024];
                arrRecvmsg = Encoding.UTF8.GetBytes("我是客户端,我要连接你!!");
    
                //发送消息
                socketclient.Send(arrRecvmsg);
                Console.WriteLine("正在连接服务端");
    
                //开启线程接受消息
                Thread th = new Thread(GetMessage);
                th.Start(socketclient);
                Console.ReadKey();
            }
            static void GetMessage(object obj)
            {
                byte[] arrRecvmsg = new byte[1024*1024];
                Socket socketclient = obj as Socket;
                while (true)//开启循环 一直读取客户端发来的消息
                {
                    int length = socketclient.Receive(arrRecvmsg);//读取消息
                    string str = Encoding.UTF8.GetString(arrRecvmsg, 0, length);
                    Console.WriteLine("收到服务端发来的消息:"+str);
                }
             
    
    
            }
        }
    }

    运行效果

     OK!简单应用就是这样啦。以上代码是学习的Demo,不能用于实际应用,只能用来学习,实际应用要复杂的很多。

     由于本人也是渣渣菜鸟,以上可叙述可能有错误。如有发现,还请告之。

     大家一起学习进步。

  • 相关阅读:
    5分钟了解为什么学习Go
    jieba gensim 相似度实现
    functiils.lru_cache缩短递归时间
    python深浅copy和赋值
    ajax上传文件 基于jquery form表单上传文件
    form组件类 钩子函数验证
    基于jquery读取input上传的文件内容
    MongonDB指令汇总
    冥想编程
    《如何阅读一本书》读书笔记
  • 原文地址:https://www.cnblogs.com/DingKing/p/8081046.html
Copyright © 2011-2022 走看看