美文网首页
【2019-10-17】 08-Socket客户端的编写--研

【2019-10-17】 08-Socket客户端的编写--研

作者: 为体验更多 | 来源:发表于2019-10-17 14:31 被阅读0次

    一.在我们讲解服务端编写之前,同样来看看该图。我们编写步骤,依此图为准。

    Socket关系图.png

    根据我们之前的说明Socket是一个网络编程接口,那么我们就得根据此特性去使用它,Socket的作者也是依据网络通信的协议进行的接口编写,所以使用思路也是做的一个继承吧。

    二. 开始上干货 我们来编写吧

    思路大纲:

    1.首先我们需要创建一个和服务端通信的的Socket,该Socket任务是和服务端连接后进行通信,他是一个Tcp/Udp客户器。步骤:设置需要连接服务端的IP和端口, 启动连接服务端服务。----这段描述,对比上图,按照顺序走过来初始化Socket对象-->Connet()。

    2.客户端和服务端连接之后呢,我们就能够和服务端进行通信了,我们使用Socket对象下的Send方法,就能够发送消息给服务器。

    3.当然客户端和服务器连接之后呢,服务器也能给客户端发送消息,所以我们使用Receive来接收服务器发送的消息。

    到此大家体会一下。我们开始编写。

    1.连接服务端代码

    08-02.png 08-03.png

    2.接收消息方法

    08-04.png 08-05.png

    3.发送消息方法

    08-06.png

    4.窗口关闭事件


    08-07.png

    三.上述代码界面:


    08-08.png

    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;

    using System.Windows;

    using System.Windows.Controls;

    using System.Windows.Data;

    using System.Windows.Documents;

    using System.Windows.Input;

    using System.Windows.Media;

    using System.Windows.Media.Imaging;

    using System.Windows.Navigation;

    using System.Windows.Shapes;

    namespace Client

    {

    /// <summary>

    /// MainWindow.xaml 的交互逻辑

    /// </summary>

    public partial class MainWindow : Window

    {

    public MainWindow()

    {

    InitializeComponent();

    }

    //Socket对象

    Socket sockClient = null;

    //接收线程

    Thread thrClient = null;

    /// <summary>

    /// 连接服务端

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>

    private void BtnCon_Click(object sender, RoutedEventArgs e)

    {

    //定义要连接Tcp服务器的的IP和端口号。

    IPAddress address = IPAddress.Parse(this.TxtIp.Text.Trim());

    IPEndPoint Ipe = new IPEndPoint(address, int.Parse(this.TxtPort.Text.Trim()));

    //创建一个用于和服务端通信的Socket对象(和服务端创建方式相同)

    sockClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    try

    {

    //编写界面提示

    this.InfoMessage.Dispatcher.Invoke(new Action(() =>

    {

    this.InfoMessage.AppendText("与服务器连接中......" + Environment.NewLine);

    }));

    //传入网络地址信息参数,开始尝试和服务端建立连接

    sockClient.Connect(Ipe);

    }

    catch (Exception ex)

    {

    MessageBox.Show("连接失败" + ex.Message, "建立连接");

    return;

    }

    //编写界面提示

    this.InfoMessage.Dispatcher.Invoke(new Action(() =>

    {

    this.InfoMessage.AppendText("与服务器连接成功" + Environment.NewLine);

    }));

    //开启一个线程用于接收服务端传递过来的消息

    thrClient = new Thread(ReceiceMsg);

    thrClient.IsBackground = true;

    thrClient.Start();

    }

    #region 接收消息

    /// <summary>

    /// 接收消息

    /// </summary>

    private void ReceiceMsg()

    {

    while (true)

    {

    //定义一个2M缓冲区

    byte[] arrMsgRec = new byte[1024 * 1024 * 2];

    int length = -1;

    try

    {

    length = sockClient.Receive(arrMsgRec);

    }

    catch (SocketException se) //服务端和客户端主动断开连接进入的异常

    {

    this.InfoMessage.Dispatcher.Invoke(new Action(() =>

    {

    this.InfoMessage.AppendText("断开连接:" + se.Message + Environment.NewLine);

    }));

    break;

    }

    catch (Exception ex)//其他方式异常处理

    {

    this.InfoMessage.Dispatcher.Invoke(new Action(() =>

    {

    this.InfoMessage.AppendText("断开连接" + ex.Message + Environment.NewLine);

    }));

    break;

    }

    if (length > 0)

    {

    //把服务端发送过来的二进制数据解码为字符串数据。

    string strMsg = Encoding.UTF8.GetString(arrMsgRec, 0, length);

    //去界面展示出来

    string Msg = "[接收] " + strMsg + Environment.NewLine;

    this.InfoMessage.Dispatcher.Invoke(new Action(() =>

    {

    this.InfoMessage.AppendText(Msg+Environment.NewLine);

    }));

    }

    }

    }

    #endregion

    #region 窗体关闭事件

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)

    {

    sockClient?.Close();

    }

    #endregion

    #region 发送消息

    private void BtnSend_Click(object sender, RoutedEventArgs e)

    {

    //组合要发送的消息

    string strMsg = "来自" + this.TxtName.Text.Trim() + ": " + this.TxtMessage.Text.Trim();

    //编码为二进制数据,为发送给服务端做准备

    byte[] arrMsg = Encoding.UTF8.GetBytes(strMsg);

    //针对消息进行个性化处理,比如消息类型判断的个性化处理,为我们后面拓展消息做准备,目前我们这里不做处理,你们可以当成这里是多余的一步。

    byte[] arrSend = new byte[arrMsg.Length];

    //把arrMsg的消息复制到arrSend里面去。 参数说明:1.被复制的数组 2.被复制数组的开始索引 2.复制终点数组 4.开始索引

    Buffer.BlockCopy(arrMsg, 0, arrSend, 0, arrMsg.Length);

    //发送数据

    sockClient.Send(arrSend);

    this.InfoMessage.Dispatcher.Invoke(new Action(() =>

    {

    this.InfoMessage.AppendText("[发送] " + this.TxtMessage.Text.Trim() + Environment.NewLine);

    }));

    }

    #endregion

    private void BtnConClose_Click(object sender, RoutedEventArgs e)

    {

    sockClient?.Close();

    }

    }

    }

    相关文章

      网友评论

          本文标题:【2019-10-17】 08-Socket客户端的编写--研

          本文链接:https://www.haomeiwen.com/subject/lmwmmctx.html