【2019-10-17】 08-Socket客户端的编写--研发部内部分享

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

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();

}

}

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容