• C# socket通信的一般步聚


    1、向服务器发出链接请求:

      需要条件:a、服务器IP;b、服务器端口

      实现:

      private IPAddress _ipAddr=IPAddress.Parse("192.168.28.126");

      int Port=8888;

      //向服务器发出连接请求
         TCPConnection conn = new TCPConnection(_ipAddr, port);
         TcpClient _tcpc = conn.Connect();

      //以下为判断是否链接得上

       if (_tcpc == null)
                {
                    MessageBox.Show("无法连接到服务器,请重试!",
                                    "错误",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Exclamation);
                }
                else
                {
                    NetworkStream netstream = _tcpc.GetStream();//提供用于访问网络的基本数据流
                    //向服务器发送用户名以确认身份


                    netstream.Write(Encoding.Unicode.GetBytes(user_tb.Text), 0, Encoding.Unicode.GetBytes(user_tb.Text).Length);

                    //得到登录结果
                    byte[] buffer = new byte[50];
                    netstream.Read(buffer, 0, buffer.Length);//该方法将数据读入 buffer 参数并返回成功读取的字节数。如果没有可以读取的数据,则 Read 方法返回 0。

                    string connResult = Encoding.Unicode.GetString(buffer).TrimEnd('\0');
                    if (connResult.Equals("cmd::Failed"))//登录不成功
                    {
                        MessageBox.Show("您的用户名已经被使用,请尝试其他用户名!",
                                        "提示",
                                        MessageBoxButtons.OK,
                                        MessageBoxIcon.Information);
                        return;
                    }
                    else  //登录成功
                    {
                        string svrskt = svrip_tb.Text + ":" + svrport_tb.Text;
                        chat_frm chatFrm = new chat_frm(user_tb.Text, netstream, svrskt);//一个巧妙的参数传递方法
                        chatFrm.Owner = this;
                        this.Hide();
                        chatFrm.Show();
                    }
                }

    2、向服务器发送数据:(逆向推进)

      1)、private NetworkStream _nws = _tcpc.GetStream();// 用于接受和发送的网络流

          ^
                     ||

        TcpClient _tcpc = conn.Connect();

          ^

          ||

        TCPConnection conn = new TCPConnection(_ipAddr, port);//向服务器发出连接请求

          ^

          ||

        private IPAddress _ipAddr=IPAddress.Parse("192.168.28.126");//服务器IP

        int Port=8888;//服务器端口

      2)、发送: _nws.Write(new byte[] { 0, 5 }, 0, 2);//发送广播请求 public override void Write(byte[] buffer, int offset, int size);

          以下为发送给指定用户:

          string _receiver = online_cb.Text;//对方用户

          _nws.Write(Encoding.Unicode.GetBytes(_receiver), 0, Encoding.Unicode.GetBytes(_receiver).Length);

          //以下为发送信息内容

           _nws.Write(Encoding.Unicode.GetBytes(sendTxt), 0, Encoding.Unicode.GetBytes(sendTxt).Length);

    3、启动接收信息线程(在page_load里直接启动)

       /// <summary>
            /// 用于接受消息的线程
            /// </summary>
            private Thread _receiveThread = null;

            /// <summary>
            /// 启动接受消息线程并显示相关信息
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void chat_frm_Load(object sender, EventArgs e)
            {
                _receiveThread = new Thread(new ThreadStart(ReceiveMsg));//接下来会执行ReceiveMsg函数
                _receiveThread.Start();

        //以下这些都是相关控件的变化:
                online_cb.Enabled = false;
                user_lb.Text   = "当前用户:" + _username;
                svrskt_lb.Text = "服务器:" + _svrskt;
            }

            /// <summary>
            /// 接受消息的线程执行体
            /// </summary>
            private void ReceiveMsg()
            {
                while (true)
                {
                    byte[] packet = new byte[_maxPacket];//_maxPacket:缓冲区的大小:private int _maxPacket = 2048;//2K的缓冲区


          //从 System.Net.Sockets.NetworkStream 读取数据。public override int Read(byte[] buffer, int offset, int size);

                   _nws.Read(packet, 0, packet.Length);

                    string _cmd = DecodingBytes(packet);

                    switch (_cmd)
                    {
                        /// "11"-服务器要求客户机更新在线列表
                        /// "12"-服务器要求客户机做闪屏振动
                        /// default-接受用户消息或者系统消息的正文
                        case "11":
                            {
                                byte[] onlineBuff = new byte[_maxPacket];
                                int byteCnt = _nws.Read(onlineBuff, 0, onlineBuff.Length);
                                IFormatter format = new BinaryFormatter();
                                MemoryStream stream = new MemoryStream();
                                stream.Write(onlineBuff, 0, byteCnt);
                                stream.Position = 0;
                                StringCollection onlineList = (StringCollection)format.Deserialize(stream);
                                online_cb.Items.Clear();
                                foreach (string onliner in onlineList)
                                {
                                    if (!onliner.Equals(_username))
                                    {
                                        online_cb.Items.Add(onliner);
                                    }
                                }
                                break;
                            }
                        case "12":
                            {
                                Nudge();
                                break;
                            }
                        default:
                            {
                                string displaytxt = Encoding.Unicode.GetString(packet);
                                chatrcd_rtb.AppendText(displaytxt);
                                _sp1.Play();
                                break;
                            }
                    }
                }
            }

    二、服务器的相关行为:

    1、服务器监听:

      IPAddress _ip = IPAddress.Parse("192.168.28.126");// Dns.GetHostAddresses(Dns.GetHostName())[0];//可能有多个,此时的IP是本地IP
         _tcpl = new TcpListener(_ip, _port);
         _tcpl.Start();//开始侦听传入的连接请求。

      while (true)
          {
                    byte[] packetBuff = new byte[_maxPacket];// 接收数据缓冲区大小64K

          /*

                    //AcceptSocket 是一个阻止方法,该方法返回可用于发送和接收数据的 Socket。
                    //如果希望避免阻止,请使用 Pending 方法来确定传入连接队列中的连接请求是否可用。
                    //返回的 Socket 是使用远程主机的 IP 地址和端口号初始化的。
                    //您可以使用 Socket 类中任何可用的 Send 和 Receive 方法与远程主机进行通信。
                    //------------使用 Socket 后,请确保调用其 Close 方法。如果应用程序相对简单,-----------
                    //请考虑使用 AcceptTcpClient 方法代替 AcceptSocket 方法。
                    //TcpClient 提供了一些通过网络在阻止同步模式下发送和接收数据的简单方法。

          */

                    Socket newClient = _tcpl.AcceptSocket();//本地TcpListener 接受新的请求
                    //返回的 Socket 是使用远程主机的 IP 地址和端口号初始化的

          newClient.Receive(packetBuff);//将接受的远程SOCKET,将数据存入接受缓冲区

          //客户端向服务器发送用户名请求:以下为接收

          string userName = Encoding.Unicode.GetString(packetBuff).TrimEnd('\0');

          /*

          //接着就进行相关的处理:

          处理的结果,发送命令给客户端:

         如:

          newClient.Send(Encoding.Unicode.GetBytes("cmd::Failed"));//发送命令为:cmd::Failed

         或newClient.Send(Encoding.Unicode.GetBytes("cmd::Successful"));

          */

         //将新连接加入转发表并创建线程为其服务
                    _transmit_tb.Add(userName, newClient);//直接把用户名、Socket对象作为一对值加入转发表

          /*定义如下:

            /// <summary>
                /// 保存所有客户端会话的哈希表
                /// </summary>
                private Hashtable _transmit_tb = new Hashtable();

          */

      }

  • 相关阅读:
    PHP 上传与下载
    PHP OOP 魔术方法
    PHP的错误处理
    初识PHP
    MUI实现上拉刷新和下拉加载
    解决 windows npm ERR! asyncWrite is not a function 问题
    浅谈angular2与angularJS的区别
    AngularJS内建服务以及自定义服务的用法
    mysql与mysqli的一些区别和方法
    数据库基础和三大范式以及基本的增删改查命令
  • 原文地址:https://www.cnblogs.com/llyfe2006/p/1874668.html
Copyright © 2020-2023  润新知