• C#Socket网络编程


    一、简介

      人与人之间远程交流通信,需要用到电话这个工具,而电脑与电脑之间通讯,也得需要一个类似电话一样的工具来接通。

    Socket·所做的就是实现电脑之间的通讯,它是一组接口,拥有相同接口的电脑可以相互传递信息。Socket是应用层与TCP/IP协议族通信的中间软件抽象层。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议

     

     

     

     

     

    二、工作原理

    先来看一张图:

     

    1、服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。

    复制代码
    //选择ip地址版本,套接字类型,协议类型,若是TCP则SocketType为Stream
    Socket socketwatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建IP地址跟端口对象 IPAddress ip = IPAddress.Any;
    //用ip跟端口号初始化得到IPEndPoint类型的实例 IPEndPoint point
    = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text)); socketwatch.Bind(point); ShowMsg("监听成功"); //监听队列 socketwatch.Listen(10);
    //开辟新线程一直监听客户端的连接
    Thread th = new Thread(Listens);
    //转为后台线程
    th.IsBackground = true;
    //传入的socketwatch为Listen的参数
    th.Start(socketwatch);

    void Listens(object o) // 参数一定得是object 类型
    {
    Socket socketwatch = o as Socket;
    while (true)
    {
    try
    {
    //等待客户端的连接,并创建一个用于通信的socket
    Socket socketSend = socketwatch.Accept(); //如果把Accept()放在主线程里会一直等待卡死界面
    ShowMsg(socketSend.RemoteEndPoint.ToString() + ": 连接成功");

    //byte[] buffer = new byte[1024 * 1024];
    //int x = socketsend.Receive(buffer);
    //string str = Encoding.UTF8.GetString(buffer, 0, x);

    //开辟新的后台线程一直接收客户端发来的消息
    Thread th1 = new Thread(Recive);
    th1.IsBackground = true;
    th1.Start(socketSend);
    }
    catch
    {}

    }

     

    复制代码

     

     

    2、在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。

    Socket socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    IPAddress iP = IPAddress.Parse(textBox1.Text);
                    IPEndPoint point = new IPEndPoint(iP, Convert.ToInt32(textBox2.Text));
                    socketSend.Connect(point);
                    ShowMsg("连接成功");

     

    3、客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

    复制代码
    //客户端发送数据
      string str = textBox4.Text.Trim();
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
                socketSend.Send(buffer);
                textBox4.Text = "";
    //服务端接收数据
    void Recive(object o)
            {
                Socket socketSend = o as Socket;
                while (true)
                {
                    try
                    {
    
                        byte[] buffer = new byte[1024 * 1024];
                        //把输入文本传给服务端,x表示实际长度
                        int x = socketSend.Receive(buffer);
                //当没有数据传输时,x长度为0,直接退出,否则会一直打印空值  
    if (x == 0) { break; } string str = Encoding.UTF8.GetString(buffer, 0, x); ShowMsg(socketSend.RemoteEndPoint + ":" + str); } catch { } } }
    //服务端发送数据

    string str = txtMsg.Text.Trim();
    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
    socketSend.Send(buffer);
    txtMsg.Text = "";

     

    //客户端接收数据,因为

    void Receives()
    {

    while (true)
    {
    try
    {

    byte[] buffer = new byte[1024 * 1024];
    //把输入文本传给服务端,x表示实际长度
    int e = socketSend.Receive(buffer);
    if (e == 0)
    {
    break;
    }
    string str = Encoding.UTF8.GetString(buffer, 0, e);
    ShowMsg(socketSend.RemoteEndPoint + ":" + str);
    }
    catch
    {}}

     
    复制代码

    三、Socket常用的方法

     

    1、绑定:socket.BInd(IPAndPiont),服务端绑定端口号,

    2、监听:socket.Listen(int x),x表示监听端口数

    3、阻塞:socket.Accept(),当有客户发起连接请求时,取消线程阻塞,所以一般不会在主线程里调用Accept

    4、连接:socket.Connect(),客户端在服务端准备就绪之后,发送连接请求

    5、socket.Close(),关闭连接

     

    四、注意事项

    1、在winform里面创建线程有时候会被系统拦截,所以只要在winform中新建了子线程都可以在程序里加入:

     //只要碰到线程问题,先把这句话加进去
    Control.CheckForIllegalCrossThreadCalls = false;

    2、Accpet方法一定不要用在主线程里面,会阻塞主界面

  • 相关阅读:
    服务器搭建(TCP套接字)-fork版(服务端)
    IDEA--tomcat日志乱码
    python-fire 链式调用解决命令行无法自动结束
    Python教程:快速入门-函数、函数参数及三元运算符
    ArcGIS_空间插值分析
    NumPy(二)
    需求评审,测试人员应该发挥怎样的价值?两分钟让你不再懵逼
    RT-Thread操作系统学习笔记(STM32F103C8T6)标准库(参考野火和江科大例程)----逻辑代码加入操作系统以LED灯闪烁为例
    约瑟夫环问题
    【Nginx39】Nginx学习:upstream服务器组模块
  • 原文地址:https://www.cnblogs.com/Darius0821/p/16546151.html